From 9d085e2abb6c1739f54507fc9ab0b4218eedf13c Mon Sep 17 00:00:00 2001
From: Ian Lin <128665735+ianlin-bbpos@users.noreply.github.com>
Date: Wed, 20 Dec 2023 07:03:10 +0800
Subject: [PATCH] Upgrade example-app to RN SDK 0.14 (#590)
* all in one commit.
* recover masked-view dependency.
* update script for Bitrise test for example android & match packages versions required by Expo.
* update bitrise.yml
* update lock file
* update rn-sdk version.
* sync dev-app code.
* some adjustments.
---
.detoxrc.json | 9 +
bitrise.yml | 5 +-
example-app/android/.gitignore | 6 -
example-app/android/app/BUCK | 55 -
example-app/android/app/build.gradle | 329 +-
example-app/android/app/build_defs.bzl | 19 -
.../android/app/src/debug/AndroidManifest.xml | 2 +-
.../ReactNativeFlipper.java | 16 +-
.../android/app/src/main/AndroidManifest.xml | 12 +-
.../MainActivity.java | 16 +-
.../MainApplication.java | 106 +-
.../MainApplicationReactNativeHost.java | 116 -
.../components/MainComponentsRegistry.java | 36 -
...ApplicationTurboModuleManagerDelegate.java | 48 -
.../android/app/src/main/jni/Android.mk | 49 -
.../jni/MainApplicationModuleProvider.cpp | 24 -
.../main/jni/MainApplicationModuleProvider.h | 16 -
...nApplicationTurboModuleManagerDelegate.cpp | 45 -
...ainApplicationTurboModuleManagerDelegate.h | 38 -
.../src/main/jni/MainComponentsRegistry.cpp | 61 -
.../app/src/main/jni/MainComponentsRegistry.h | 32 -
.../android/app/src/main/jni/OnLoad.cpp | 11 -
.../res/drawable/rn_edit_text_material.xml | 2 +-
.../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 3300 -> 8377 bytes
.../mipmap-hdpi/ic_launcher_foreground.png | Bin 3300 -> 8031 bytes
.../res/mipmap-hdpi/ic_launcher_round.png | Bin 4103 -> 10372 bytes
.../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2048 -> 5199 bytes
.../mipmap-mdpi/ic_launcher_foreground.png | Bin 2309 -> 5079 bytes
.../res/mipmap-mdpi/ic_launcher_round.png | Bin 2613 -> 6526 bytes
.../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4535 -> 11624 bytes
.../mipmap-xhdpi/ic_launcher_foreground.png | Bin 4517 -> 11145 bytes
.../res/mipmap-xhdpi/ic_launcher_round.png | Bin 5673 -> 14257 bytes
.../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 7345 -> 18266 bytes
.../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 7179 -> 18064 bytes
.../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 9091 -> 22474 bytes
.../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 10108 -> 25203 bytes
.../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 9704 -> 25030 bytes
.../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 12469 -> 30705 bytes
.../main/res/xml/network_security_config.xml | 8 -
.../ReactNativeFlipper.java | 20 +
example-app/android/build.gradle | 42 +-
example-app/android/gradle.properties | 14 +-
.../android/gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 60756 bytes
.../gradle/wrapper/gradle-wrapper.properties | 3 +-
example-app/android/gradlew | 6 +
example-app/android/gradlew.bat | 14 +-
example-app/android/settings.gradle | 7 +-
example-app/ios/.gitignore | 1 +
example-app/ios/.xcode.env | 11 +
example-app/ios/Podfile | 66 +-
example-app/ios/Podfile.lock | 782 +-
example-app/ios/Podfile.properties.json | 3 +-
example-app/ios/exampleapp.entitlements | 8 -
.../ios/exampleapp.xcodeproj/project.pbxproj | 109 +-
example-app/ios/exampleapp/AppDelegate.h | 6 +-
example-app/ios/exampleapp/AppDelegate.mm | 98 +-
...twork@2x.png => App-Icon-1024x1024@1x.png} | Bin
.../AppIcon.appiconset/App-Icon-20x20@1x.png | Bin 583 -> 0 bytes
.../AppIcon.appiconset/App-Icon-20x20@2x.png | Bin 1562 -> 0 bytes
.../AppIcon.appiconset/App-Icon-20x20@3x.png | Bin 2642 -> 0 bytes
.../AppIcon.appiconset/App-Icon-29x29@1x.png | Bin 1028 -> 0 bytes
.../AppIcon.appiconset/App-Icon-29x29@2x.png | Bin 2492 -> 0 bytes
.../AppIcon.appiconset/App-Icon-29x29@3x.png | Bin 4307 -> 0 bytes
.../AppIcon.appiconset/App-Icon-40x40@1x.png | Bin 1562 -> 0 bytes
.../AppIcon.appiconset/App-Icon-40x40@2x.png | Bin 3806 -> 0 bytes
.../AppIcon.appiconset/App-Icon-40x40@3x.png | Bin 6565 -> 0 bytes
.../AppIcon.appiconset/App-Icon-60x60@2x.png | Bin 6565 -> 0 bytes
.../AppIcon.appiconset/App-Icon-60x60@3x.png | Bin 10430 -> 0 bytes
.../AppIcon.appiconset/App-Icon-76x76@1x.png | Bin 3499 -> 0 bytes
.../AppIcon.appiconset/App-Icon-76x76@2x.png | Bin 8492 -> 0 bytes
.../App-Icon-83.5x83.5@2x.png | Bin 9469 -> 0 bytes
.../AppIcon.appiconset/Contents.json | 116 +-
example-app/ios/exampleapp/Info.plist | 2 +
.../ios/exampleapp/Supporting/Expo.plist | 6 +-
.../exampleapp/exampleapp-Bridging-Header.h | 3 +
example-app/package.json | 38 +-
example-app/src/App.tsx | 16 +-
example-app/src/colors.ts | 1 +
example-app/src/components/Collapse.tsx | 1 +
.../src/screens/CollectCardPaymentScreen.tsx | 385 +-
example-app/src/screens/DatabaseScreen.tsx | 93 +
example-app/src/screens/HomeScreen.tsx | 86 +-
.../src/screens/ReadReusableCardScreen.tsx | 118 -
.../src/screens/RefundPaymentScreen.tsx | 90 +-
example-app/src/screens/SetupIntentScreen.tsx | 65 +-
example-app/yarn.lock | 6330 +++++++----------
package.json | 1 +
87 files changed, 4271 insertions(+), 5331 deletions(-)
delete mode 100644 example-app/android/app/BUCK
delete mode 100644 example-app/android/app/build_defs.bzl
delete mode 100644 example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/MainApplicationReactNativeHost.java
delete mode 100644 example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/components/MainComponentsRegistry.java
delete mode 100644 example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
delete mode 100644 example-app/android/app/src/main/jni/Android.mk
delete mode 100644 example-app/android/app/src/main/jni/MainApplicationModuleProvider.cpp
delete mode 100644 example-app/android/app/src/main/jni/MainApplicationModuleProvider.h
delete mode 100644 example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
delete mode 100644 example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
delete mode 100644 example-app/android/app/src/main/jni/MainComponentsRegistry.cpp
delete mode 100644 example-app/android/app/src/main/jni/MainComponentsRegistry.h
delete mode 100644 example-app/android/app/src/main/jni/OnLoad.cpp
delete mode 100644 example-app/android/app/src/main/res/xml/network_security_config.xml
create mode 100644 example-app/android/app/src/release/java/com/example/stripeterminalreactnative/ReactNativeFlipper.java
create mode 100644 example-app/ios/.xcode.env
delete mode 100644 example-app/ios/exampleapp.entitlements
rename example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/{ItunesArtwork@2x.png => App-Icon-1024x1024@1x.png} (100%)
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png
delete mode 100644 example-app/ios/exampleapp/Images.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png
create mode 100644 example-app/ios/exampleapp/exampleapp-Bridging-Header.h
create mode 100644 example-app/src/screens/DatabaseScreen.tsx
delete mode 100644 example-app/src/screens/ReadReusableCardScreen.tsx
diff --git a/.detoxrc.json b/.detoxrc.json
index ab749f74..03cd4da2 100644
--- a/.detoxrc.json
+++ b/.detoxrc.json
@@ -7,6 +7,11 @@
"binaryPath": "example-app/ios/build/Build/Products/Debug-iphonesimulator/StripeTerminalReactNativeExampleApp.app",
"build": "xcodebuild -workspace example-app/ios/exampleapp.xcworkspace -configuration Debug -scheme exampleapp -destination 'platform=iOS Simulator,name=iPhone SE (3rd generation)' -derivedDataPath example-app/ios/build"
},
+ "android.example.debug": {
+ "type": "android.apk",
+ "binaryPath": "example-app/android/app/build/outputs/apk/debug/app-debug.apk",
+ "build": "cd example-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug ; cd -"
+ },
"ios.debug": {
"type": "ios.app",
"binaryPath": "dev-app/ios/build/Build/Products/Debug-iphonesimulator/StripeTerminalReactNativeDevApp.app",
@@ -56,6 +61,10 @@
"device": "simulator",
"app": "ios.example.debug"
},
+ "android.example": {
+ "device": "ci-emulator",
+ "app": "android.example.debug"
+ },
"ios": {
"device": "simulator",
"app": "ios.debug"
diff --git a/bitrise.yml b/bitrise.yml
index b85a562c..e33b04a2 100644
--- a/bitrise.yml
+++ b/bitrise.yml
@@ -127,10 +127,9 @@ workflows:
- api_level: '30'
- yarn@0:
inputs:
- - command: build:android:ci
+ - command: e2e:build:example:android
- cache_local_deps: 'yes'
- - workdir: example-app
- title: yarn build:android
+ title: yarn e2e:build:example:android
before_run:
- prep_all
after_run:
diff --git a/example-app/android/.gitignore b/example-app/android/.gitignore
index 64436baa..877b87e9 100644
--- a/example-app/android/.gitignore
+++ b/example-app/android/.gitignore
@@ -11,11 +11,5 @@ local.properties
*.iml
*.hprof
-# BUCK
-buck-out/
-\.buckd/
-*.keystore
-!debug.keystore
-
# Bundle artifacts
*.jsbundle
diff --git a/example-app/android/app/BUCK b/example-app/android/app/BUCK
deleted file mode 100644
index e3343c49..00000000
--- a/example-app/android/app/BUCK
+++ /dev/null
@@ -1,55 +0,0 @@
-# To learn about Buck see [Docs](https://buckbuild.com/).
-# To run your application with Buck:
-# - install Buck
-# - `npm start` - to start the packager
-# - `cd android`
-# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
-# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
-# - `buck install -r android/app` - compile, install and run application
-#
-
-load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
-
-lib_deps = []
-
-create_aar_targets(glob(["libs/*.aar"]))
-
-create_jar_targets(glob(["libs/*.jar"]))
-
-android_library(
- name = "all-libs",
- exported_deps = lib_deps,
-)
-
-android_library(
- name = "app-code",
- srcs = glob([
- "src/main/java/**/*.java",
- ]),
- deps = [
- ":all-libs",
- ":build_config",
- ":res",
- ],
-)
-
-android_build_config(
- name = "build_config",
- package = "com.example.stripeterminalreactnative",
-)
-
-android_resource(
- name = "res",
- package = "com.example.stripeterminalreactnative",
- res = "src/main/res",
-)
-
-android_binary(
- name = "app",
- keystore = "//android/keystores:debug",
- manifest = "src/main/AndroidManifest.xml",
- package_type = "debug",
- deps = [
- ":app-code",
- ],
-)
diff --git a/example-app/android/app/build.gradle b/example-app/android/app/build.gradle
index 3bd5465f..7bc242cc 100644
--- a/example-app/android/app/build.gradle
+++ b/example-app/android/app/build.gradle
@@ -1,232 +1,95 @@
apply plugin: "com.android.application"
-
-import com.android.build.OutputFile
-import org.apache.tools.ant.taskdefs.condition.Os
-
-/**
- * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
- * and bundleReleaseJsAndAssets).
- * These basically call `react-native bundle` with the correct arguments during the Android build
- * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
- * bundle directly from the development server. Below you can see all the possible configurations
- * and their defaults. If you decide to add a configuration block, make sure to add it before the
- * `apply from: "../../node_modules/react-native/react.gradle"` line.
- *
- * project.ext.react = [
- * // the name of the generated asset file containing your JS bundle
- * bundleAssetName: "index.android.bundle",
- *
- * // the entry file for bundle generation. If none specified and
- * // "index.android.js" exists, it will be used. Otherwise "index.js" is
- * // default. Can be overridden with ENTRY_FILE environment variable.
- * entryFile: "index.android.js",
- *
- * // https://reactnative.dev/docs/performance#enable-the-ram-format
- * bundleCommand: "ram-bundle",
- *
- * // whether to bundle JS and assets in debug mode
- * bundleInDebug: false,
- *
- * // whether to bundle JS and assets in release mode
- * bundleInRelease: true,
- *
- * // whether to bundle JS and assets in another build variant (if configured).
- * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
- * // The configuration property can be in the following formats
- * // 'bundleIn${productFlavor}${buildType}'
- * // 'bundleIn${buildType}'
- * // bundleInFreeDebug: true,
- * // bundleInPaidRelease: true,
- * // bundleInBeta: true,
- *
- * // whether to disable dev mode in custom build variants (by default only disabled in release)
- * // for example: to disable dev mode in the staging build type (if configured)
- * devDisabledInStaging: true,
- * // The configuration property can be in the following formats
- * // 'devDisabledIn${productFlavor}${buildType}'
- * // 'devDisabledIn${buildType}'
- *
- * // the root of your project, i.e. where "package.json" lives
- * root: "../../",
- *
- * // where to put the JS bundle asset in debug mode
- * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
- *
- * // where to put the JS bundle asset in release mode
- * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
- *
- * // where to put drawable resources / React Native assets, e.g. the ones you use via
- * // require('./image.png')), in debug mode
- * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
- *
- * // where to put drawable resources / React Native assets, e.g. the ones you use via
- * // require('./image.png')), in release mode
- * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
- *
- * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
- * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
- * // date; if you have any other folders that you want to ignore for performance reasons (gradle
- * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
- * // for example, you might want to remove it from here.
- * inputExcludes: ["android/**", "ios/**"],
- *
- * // override which node gets called and with what additional arguments
- * nodeExecutableAndArgs: ["node"],
- *
- * // supply additional arguments to the packager
- * extraPackagerArgs: []
- * ]
- */
+apply plugin: "com.facebook.react"
def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()
-project.ext.react = [
- entryFile: ["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android"].execute(null, rootDir).text.trim(),
- enableHermes: (findProperty('expo.jsEngine') ?: "jsc") == "hermes",
- cliPath: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/cli.js",
- hermesCommand: new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/%OS-BIN%/hermesc",
- composeSourceMapsPath: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/scripts/compose-source-maps.js",
-]
-
-apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../react.gradle")
-
/**
- * Set this to true to create two separate APKs instead of one:
- * - An APK that only works on ARM devices
- * - An APK that only works on x86 devices
- * The advantage is the size of the APK is reduced by about 4MB.
- * Upload all the APKs to the Play Store and people will download
- * the correct one based on the CPU architecture of their device.
+ * This is the configuration block to customize your React Native Android app.
+ * By default you don't need to apply any configuration, just uncomment the lines you need.
*/
-def enableSeparateBuildPerCPUArchitecture = false
+react {
+ entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim())
+ reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
+ hermesCommand = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/sdks/hermesc/%OS-BIN%/hermesc"
+ codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
+
+ // Use Expo CLI to bundle the app, this ensures the Metro config
+ // works correctly with Expo projects.
+ cliFile = new File(["node", "--print", "require.resolve('@expo/cli')"].execute(null, rootDir).text.trim())
+ bundleCommand = "export:embed"
+
+ /* Folders */
+ // The root of your project, i.e. where "package.json" lives. Default is '..'
+ // root = file("../")
+ // The folder where the react-native NPM package is. Default is ../node_modules/react-native
+ // reactNativeDir = file("../node_modules/react-native")
+ // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
+ // codegenDir = file("../node_modules/@react-native/codegen")
+
+ /* Variants */
+ // The list of variants to that are debuggable. For those we're going to
+ // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
+ // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
+ // debuggableVariants = ["liteDebug", "prodDebug"]
+
+ /* Bundling */
+ // A list containing the node command and its flags. Default is just 'node'.
+ // nodeExecutableAndArgs = ["node"]
+
+ //
+ // The path to the CLI configuration file. Default is empty.
+ // bundleConfig = file(../rn-cli.config.js)
+ //
+ // The name of the generated asset file containing your JS bundle
+ // bundleAssetName = "MyApplication.android.bundle"
+ //
+ // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
+ // entryFile = file("../js/MyApplication.android.js")
+ //
+ // A list of extra flags to pass to the 'bundle' commands.
+ // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
+ // extraPackagerArgs = []
+
+ /* Hermes Commands */
+ // The hermes compiler command to run. By default it is 'hermesc'
+ // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
+ //
+ // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
+ // hermesFlags = ["-O", "-output-source-map"]
+}
/**
- * Run Proguard to shrink the Java bytecode in release builds.
+ * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
*/
def enableProguardInReleaseBuilds = (findProperty('android.enableProguardInReleaseBuilds') ?: false).toBoolean()
/**
- * The preferred build flavor of JavaScriptCore.
+ * The preferred build flavor of JavaScriptCore (JSC)
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
- * give correct results when using with locales other than en-US. Note that
+ * give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
-/**
- * Whether to enable the Hermes VM.
- *
- * This should be set on project.ext.react and that value will be read here. If it is not set
- * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
- * and the benefits of using Hermes will therefore be sharply reduced.
- */
-def enableHermes = project.ext.react.get("enableHermes", false);
-
-/**
- * Architectures to build native code for.
- */
-def reactNativeArchitectures() {
- def value = project.getProperties().get("reactNativeArchitectures")
- return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
-}
-
android {
ndkVersion rootProject.ext.ndkVersion
compileSdkVersion rootProject.ext.compileSdkVersion
+ namespace 'com.example.stripeterminalreactnative'
defaultConfig {
applicationId 'com.example.stripeterminalreactnative'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0.0"
- buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
-
- if (isNewArchitectureEnabled()) {
- // We configure the NDK build only if you decide to opt-in for the New Architecture.
- externalNativeBuild {
- ndkBuild {
- arguments "APP_PLATFORM=android-21",
- "APP_STL=c++_shared",
- "NDK_TOOLCHAIN_VERSION=clang",
- "GENERATED_SRC_DIR=$buildDir/generated/source",
- "PROJECT_BUILD_DIR=$buildDir",
- "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
- "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
- cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
- cppFlags "-std=c++17"
- // Make sure this target name is the same you specify inside the
- // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
- targets "exampleapp_appmodules"
-
- // Fix for windows limit on number of character in file paths and in command lines
- if (Os.isFamily(Os.FAMILY_WINDOWS)) {
- arguments "NDK_APP_SHORT_COMMANDS=true"
- }
- }
- }
- if (!enableSeparateBuildPerCPUArchitecture) {
- ndk {
- abiFilters (*reactNativeArchitectures())
- }
- }
- }
- }
-
- if (isNewArchitectureEnabled()) {
- // We configure the NDK build only if you decide to opt-in for the New Architecture.
- externalNativeBuild {
- ndkBuild {
- path "$projectDir/src/main/jni/Android.mk"
- }
- }
- def reactAndroidProjectDir = project(':ReactAndroid').projectDir
- def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
- dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
- from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
- into("$buildDir/react-ndk/exported")
- }
- def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
- dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
- from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
- into("$buildDir/react-ndk/exported")
- }
- afterEvaluate {
- // If you wish to add a custom TurboModule or component locally,
- // you should uncomment this line.
- // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
- preDebugBuild.dependsOn(packageReactNdkDebugLibs)
- preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
- // Due to a bug inside AGP, we have to explicitly set a dependency
- // between configureNdkBuild* tasks and the preBuild tasks.
- // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
- configureNdkBuildRelease.dependsOn(preReleaseBuild)
- configureNdkBuildDebug.dependsOn(preDebugBuild)
- reactNativeArchitectures().each { architecture ->
- tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
- dependsOn("preDebugBuild")
- }
- tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
- dependsOn("preReleaseBuild")
- }
- }
- }
- }
-
- splits {
- abi {
- reset()
- enable enableSeparateBuildPerCPUArchitecture
- universalApk false // If true, also generate a universal APK
- include (*reactNativeArchitectures())
- }
+ buildConfigField("boolean", "REACT_NATIVE_UNSTABLE_USE_RUNTIME_SCHEDULER_ALWAYS", (findProperty("reactNative.unstable_useRuntimeSchedulerAlways") ?: true).toString())
}
signingConfigs {
debug {
@@ -244,25 +107,11 @@ android {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
+ shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false)
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
-
- // applicationVariants are e.g. debug, release
- applicationVariants.all { variant ->
- variant.outputs.each { output ->
- // For each separate APK per architecture, set a unique version code as described here:
- // https://developer.android.com/studio/build/configure-apk-splits.html
- def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
- def abi = output.getFilter(OutputFile.ABI)
- if (abi != null) { // null for the universal-debug, universal-release variants
- output.versionCodeOverride =
- versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
- }
-
- }
- }
}
// Apply static values from `gradle.properties` to the `android.packagingOptions`
@@ -286,82 +135,46 @@ android {
}
dependencies {
- implementation fileTree(dir: "libs", include: ["*.jar"])
-
- //noinspection GradleDynamicVersion
- implementation "com.facebook.react:react-native:+" // From node_modules
+ // The version of react-native is set by the React Native Gradle Plugin
+ implementation("com.facebook.react:react-android")
def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";
+ def frescoVersion = rootProject.ext.frescoVersion
// If your app supports Android versions before Ice Cream Sandwich (API level 14)
- // All fresco packages should use the same version
if (isGifEnabled || isWebpEnabled) {
- implementation 'com.facebook.fresco:fresco:2.0.0'
- implementation 'com.facebook.fresco:imagepipeline-okhttp3:2.0.0'
+ implementation("com.facebook.fresco:fresco:${frescoVersion}")
+ implementation("com.facebook.fresco:imagepipeline-okhttp3:${frescoVersion}")
}
if (isGifEnabled) {
// For animated gif support
- implementation 'com.facebook.fresco:animated-gif:2.0.0'
+ implementation("com.facebook.fresco:animated-gif:${frescoVersion}")
}
if (isWebpEnabled) {
// For webp support
- implementation 'com.facebook.fresco:webpsupport:2.0.0'
+ implementation("com.facebook.fresco:webpsupport:${frescoVersion}")
if (isWebpAnimatedEnabled) {
// Animated webp support
- implementation 'com.facebook.fresco:animated-webp:2.0.0'
+ implementation("com.facebook.fresco:animated-webp:${frescoVersion}")
}
}
- implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
- debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
- exclude group:'com.facebook.fbjni'
- }
+ debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
- exclude group:'com.facebook.flipper'
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
- debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
- exclude group:'com.facebook.flipper'
- }
+ debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
- if (enableHermes) {
- debugImplementation files(new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim(), "../android/hermes-debug.aar"))
- releaseImplementation files(new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim(), "../android/hermes-release.aar"))
+ if (hermesEnabled.toBoolean()) {
+ implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
}
-if (isNewArchitectureEnabled()) {
- // If new architecture is enabled, we let you build RN from source
- // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
- // This will be applied to all the imported transtitive dependency.
- configurations.all {
- resolutionStrategy.dependencySubstitution {
- substitute(module("com.facebook.react:react-native"))
- .using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
- }
- }
-}
-
-// Run this once to be able to run the application with BUCK
-// puts all compile dependencies into folder libs for BUCK to use
-task copyDownloadableDepsToLibs(type: Copy) {
- from configurations.implementation
- into 'libs'
-}
-
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
applyNativeModulesAppBuildGradle(project)
-
-def isNewArchitectureEnabled() {
- // To opt-in for the New Architecture, you can either:
- // - Set `newArchEnabled` to true inside the `gradle.properties` file
- // - Invoke gradle with `-newArchEnabled=true`
- // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
- return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
-}
diff --git a/example-app/android/app/build_defs.bzl b/example-app/android/app/build_defs.bzl
deleted file mode 100644
index fff270f8..00000000
--- a/example-app/android/app/build_defs.bzl
+++ /dev/null
@@ -1,19 +0,0 @@
-"""Helper definitions to glob .aar and .jar targets"""
-
-def create_aar_targets(aarfiles):
- for aarfile in aarfiles:
- name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
- lib_deps.append(":" + name)
- android_prebuilt_aar(
- name = name,
- aar = aarfile,
- )
-
-def create_jar_targets(jarfiles):
- for jarfile in jarfiles:
- name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
- lib_deps.append(":" + name)
- prebuilt_jar(
- name = name,
- binary_jar = jarfile,
- )
diff --git a/example-app/android/app/src/debug/AndroidManifest.xml b/example-app/android/app/src/debug/AndroidManifest.xml
index 99e38fc5..3ec2507b 100644
--- a/example-app/android/app/src/debug/AndroidManifest.xml
+++ b/example-app/android/app/src/debug/AndroidManifest.xml
@@ -3,5 +3,5 @@
-
+
diff --git a/example-app/android/app/src/debug/java/com/example/stripeterminalreactnative/ReactNativeFlipper.java b/example-app/android/app/src/debug/java/com/example/stripeterminalreactnative/ReactNativeFlipper.java
index 4fcd6a4d..585827f4 100644
--- a/example-app/android/app/src/debug/java/com/example/stripeterminalreactnative/ReactNativeFlipper.java
+++ b/example-app/android/app/src/debug/java/com/example/stripeterminalreactnative/ReactNativeFlipper.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) Facebook, Inc. and its affiliates.
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
*
*
This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
@@ -17,22 +17,27 @@
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
-import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
+import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;
+/**
+ * Class responsible of loading Flipper inside your React Native application. This is the debug
+ * flavor of it. Here you can add your own plugins and customize the Flipper setup.
+ */
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
+
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
- client.addPlugin(new ReactFlipperPlugin());
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
+
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
NetworkingModule.setCustomClientBuilder(
new NetworkingModule.CustomClientBuilder() {
@@ -43,12 +48,13 @@ public void apply(OkHttpClient.Builder builder) {
});
client.addPlugin(networkFlipperPlugin);
client.start();
+
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
// Hence we run if after all native modules have been initialized
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
- new ReactInstanceManager.ReactInstanceEventListener() {
+ new ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
@@ -66,4 +72,4 @@ public void run() {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/example-app/android/app/src/main/AndroidManifest.xml b/example-app/android/app/src/main/AndroidManifest.xml
index 4546cc89..ae82579e 100644
--- a/example-app/android/app/src/main/AndroidManifest.xml
+++ b/example-app/android/app/src/main/AndroidManifest.xml
@@ -1,5 +1,4 @@
-
-
+
@@ -16,12 +15,11 @@
-
-
-
+
+
+
-
@@ -36,4 +34,4 @@
-
+
\ No newline at end of file
diff --git a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainActivity.java b/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainActivity.java
index fb5924c5..5b9b4079 100644
--- a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainActivity.java
+++ b/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainActivity.java
@@ -5,7 +5,8 @@
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
-import com.facebook.react.ReactRootView;
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactActivityDelegate;
import expo.modules.ReactActivityDelegateWrapper;
@@ -28,11 +29,18 @@ protected String getMainComponentName() {
return "main";
}
+ /**
+ * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
+ * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
+ * (aka React 18) with two boolean flags.
+ */
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
- return new ReactActivityDelegateWrapper(this,
- new ReactActivityDelegate(this, getMainComponentName())
- );
+ return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
+ this,
+ getMainComponentName(),
+ // If you opted-in for the New Architecture, we enable the Fabric Renderer.
+ DefaultNewArchitectureEntryPoint.getFabricEnabled()));
}
/**
diff --git a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainApplication.java b/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainApplication.java
index c11bc41b..f63ed50a 100644
--- a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainApplication.java
+++ b/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/MainApplication.java
@@ -1,69 +1,74 @@
package com.example.stripeterminalreactnative;
import android.app.Application;
-import android.content.Context;
import android.content.res.Configuration;
import androidx.annotation.NonNull;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
-import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.config.ReactFeatureFlags;
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
-import com.example.stripeterminalreactnative.newarchitecture.MainApplicationReactNativeHost;
import expo.modules.ApplicationLifecycleDispatcher;
import expo.modules.ReactNativeHostWrapper;
-import java.lang.reflect.InvocationTargetException;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
- private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(
- this,
- new ReactNativeHost(this) {
- @Override
- public boolean getUseDeveloperSupport() {
- return BuildConfig.DEBUG;
- }
- @Override
- protected List getPackages() {
- @SuppressWarnings("UnnecessaryLocalVariable")
- List packages = new PackageList(this).getPackages();
- // Packages that cannot be autolinked yet can be added manually here, for example:
- // packages.add(new MyReactNativePackage());
- return packages;
- }
+ private final ReactNativeHost mReactNativeHost =
+ new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
+ @Override
+ public boolean getUseDeveloperSupport() {
+ return BuildConfig.DEBUG;
+ }
- @Override
- protected String getJSMainModuleName() {
- return "index";
- }
- });
+ @Override
+ protected List getPackages() {
+ @SuppressWarnings("UnnecessaryLocalVariable")
+ List packages = new PackageList(this).getPackages();
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ return packages;
+ }
- private final ReactNativeHost mNewArchitectureNativeHost =
- new ReactNativeHostWrapper(this, new MainApplicationReactNativeHost(this));
+ @Override
+ protected String getJSMainModuleName() {
+ return ".expo/.virtual-metro-entry";
+ }
+
+ @Override
+ protected boolean isNewArchEnabled() {
+ return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
+ }
+
+ @Override
+ protected Boolean isHermesEnabled() {
+ return BuildConfig.IS_HERMES_ENABLED;
+ }
+ });
@Override
public ReactNativeHost getReactNativeHost() {
- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
- return mNewArchitectureNativeHost;
- } else {
- return mReactNativeHost;
- }
+ return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
- // If you opted-in for the New Architecture, we enable the TurboModule system
- ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
SoLoader.init(this, /* native exopackage */ false);
-
- initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
+ if (!BuildConfig.REACT_NATIVE_UNSTABLE_USE_RUNTIME_SCHEDULER_ALWAYS) {
+ ReactFeatureFlags.unstable_useRuntimeSchedulerAlways = false;
+ }
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ // If you opted-in for the New Architecture, we load the native entry point for this app.
+ DefaultNewArchitectureEntryPoint.load();
+ }
+ ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
ApplicationLifecycleDispatcher.onApplicationCreate(this);
}
@@ -72,35 +77,4 @@ public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
}
-
- /**
- * Loads Flipper in React Native templates. Call this in the onCreate method with something like
- * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
- *
- * @param context
- * @param reactInstanceManager
- */
- private static void initializeFlipper(
- Context context, ReactInstanceManager reactInstanceManager) {
- if (BuildConfig.DEBUG) {
- try {
- /*
- We use reflection here to pick up the class that initializes Flipper,
- since Flipper library is not available in release mode
- */
- Class> aClass = Class.forName("com.example.stripeterminalreactnative.ReactNativeFlipper");
- aClass
- .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
- .invoke(null, context, reactInstanceManager);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
- }
}
diff --git a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/MainApplicationReactNativeHost.java b/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/MainApplicationReactNativeHost.java
deleted file mode 100644
index 0b1b4f9d..00000000
--- a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/MainApplicationReactNativeHost.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package com.example.stripeterminalreactnative.newarchitecture;
-
-import android.app.Application;
-import androidx.annotation.NonNull;
-import com.facebook.react.PackageList;
-import com.facebook.react.ReactInstanceManager;
-import com.facebook.react.ReactNativeHost;
-import com.facebook.react.ReactPackage;
-import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
-import com.facebook.react.bridge.JSIModulePackage;
-import com.facebook.react.bridge.JSIModuleProvider;
-import com.facebook.react.bridge.JSIModuleSpec;
-import com.facebook.react.bridge.JSIModuleType;
-import com.facebook.react.bridge.JavaScriptContextHolder;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.UIManager;
-import com.facebook.react.fabric.ComponentFactory;
-import com.facebook.react.fabric.CoreComponentsRegistry;
-import com.facebook.react.fabric.EmptyReactNativeConfig;
-import com.facebook.react.fabric.FabricJSIModuleProvider;
-import com.facebook.react.uimanager.ViewManagerRegistry;
-import com.example.stripeterminalreactnative.BuildConfig;
-import com.example.stripeterminalreactnative.newarchitecture.components.MainComponentsRegistry;
-import com.example.stripeterminalreactnative.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
- * TurboModule delegates and the Fabric Renderer.
- *
- * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
- * `newArchEnabled` property). Is ignored otherwise.
- */
-public class MainApplicationReactNativeHost extends ReactNativeHost {
- public MainApplicationReactNativeHost(Application application) {
- super(application);
- }
-
- @Override
- public boolean getUseDeveloperSupport() {
- return BuildConfig.DEBUG;
- }
-
- @Override
- protected List getPackages() {
- List packages = new PackageList(this).getPackages();
- // Packages that cannot be autolinked yet can be added manually here, for example:
- // packages.add(new MyReactNativePackage());
- // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
- // packages.add(new TurboReactPackage() { ... });
- // If you have custom Fabric Components, their ViewManagers should also be loaded here
- // inside a ReactPackage.
- return packages;
- }
-
- @Override
- protected String getJSMainModuleName() {
- return "index";
- }
-
- @NonNull
- @Override
- protected ReactPackageTurboModuleManagerDelegate.Builder
- getReactPackageTurboModuleManagerDelegateBuilder() {
- // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
- // for the new architecture and to use TurboModules correctly.
- return new MainApplicationTurboModuleManagerDelegate.Builder();
- }
-
- @Override
- protected JSIModulePackage getJSIModulePackage() {
- return new JSIModulePackage() {
- @Override
- public List getJSIModules(
- final ReactApplicationContext reactApplicationContext,
- final JavaScriptContextHolder jsContext) {
- final List specs = new ArrayList<>();
-
- // Here we provide a new JSIModuleSpec that will be responsible of providing the
- // custom Fabric Components.
- specs.add(
- new JSIModuleSpec() {
- @Override
- public JSIModuleType getJSIModuleType() {
- return JSIModuleType.UIManager;
- }
-
- @Override
- public JSIModuleProvider getJSIModuleProvider() {
- final ComponentFactory componentFactory = new ComponentFactory();
- CoreComponentsRegistry.register(componentFactory);
-
- // Here we register a Components Registry.
- // The one that is generated with the template contains no components
- // and just provides you the one from React Native core.
- MainComponentsRegistry.register(componentFactory);
-
- final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
-
- ViewManagerRegistry viewManagerRegistry =
- new ViewManagerRegistry(
- reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
-
- return new FabricJSIModuleProvider(
- reactApplicationContext,
- componentFactory,
- new EmptyReactNativeConfig(),
- viewManagerRegistry);
- }
- });
- return specs;
- }
- };
- }
-}
diff --git a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/components/MainComponentsRegistry.java b/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/components/MainComponentsRegistry.java
deleted file mode 100644
index 36887a3c..00000000
--- a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/components/MainComponentsRegistry.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.example.stripeterminalreactnative.newarchitecture.components;
-
-import com.facebook.jni.HybridData;
-import com.facebook.proguard.annotations.DoNotStrip;
-import com.facebook.react.fabric.ComponentFactory;
-import com.facebook.soloader.SoLoader;
-
-/**
- * Class responsible to load the custom Fabric Components. This class has native methods and needs a
- * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
- * folder for you).
- *
- * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
- * `newArchEnabled` property). Is ignored otherwise.
- */
-@DoNotStrip
-public class MainComponentsRegistry {
- static {
- SoLoader.loadLibrary("fabricjni");
- }
-
- @DoNotStrip private final HybridData mHybridData;
-
- @DoNotStrip
- private native HybridData initHybrid(ComponentFactory componentFactory);
-
- @DoNotStrip
- private MainComponentsRegistry(ComponentFactory componentFactory) {
- mHybridData = initHybrid(componentFactory);
- }
-
- @DoNotStrip
- public static MainComponentsRegistry register(ComponentFactory componentFactory) {
- return new MainComponentsRegistry(componentFactory);
- }
-}
diff --git a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
deleted file mode 100644
index 32ce0af8..00000000
--- a/example-app/android/app/src/main/java/com/example/stripeterminalreactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.example.stripeterminalreactnative.newarchitecture.modules;
-
-import com.facebook.jni.HybridData;
-import com.facebook.react.ReactPackage;
-import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.soloader.SoLoader;
-import java.util.List;
-
-/**
- * Class responsible to load the TurboModules. This class has native methods and needs a
- * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
- * folder for you).
- *
- *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
- * `newArchEnabled` property). Is ignored otherwise.
- */
-public class MainApplicationTurboModuleManagerDelegate
- extends ReactPackageTurboModuleManagerDelegate {
-
- private static volatile boolean sIsSoLibraryLoaded;
-
- protected MainApplicationTurboModuleManagerDelegate(
- ReactApplicationContext reactApplicationContext, List packages) {
- super(reactApplicationContext, packages);
- }
-
- protected native HybridData initHybrid();
-
- native boolean canCreateTurboModule(String moduleName);
-
- public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
- protected MainApplicationTurboModuleManagerDelegate build(
- ReactApplicationContext context, List packages) {
- return new MainApplicationTurboModuleManagerDelegate(context, packages);
- }
- }
-
- @Override
- protected synchronized void maybeLoadOtherSoLibraries() {
- if (!sIsSoLibraryLoaded) {
- // If you change the name of your application .so file in the Android.mk file,
- // make sure you update the name here as well.
- SoLoader.loadLibrary("exampleapp_appmodules");
- sIsSoLibraryLoaded = true;
- }
- }
-}
diff --git a/example-app/android/app/src/main/jni/Android.mk b/example-app/android/app/src/main/jni/Android.mk
deleted file mode 100644
index 2eb366fb..00000000
--- a/example-app/android/app/src/main/jni/Android.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-THIS_DIR := $(call my-dir)
-
-include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
-
-# If you wish to add a custom TurboModule or Fabric component in your app you
-# will have to include the following autogenerated makefile.
-# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
-include $(CLEAR_VARS)
-
-LOCAL_PATH := $(THIS_DIR)
-
-# You can customize the name of your application .so file here.
-LOCAL_MODULE := exampleapp_appmodules
-
-LOCAL_C_INCLUDES := $(LOCAL_PATH)
-LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
-LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
-
-# If you wish to add a custom TurboModule or Fabric component in your app you
-# will have to uncomment those lines to include the generated source
-# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
-#
-# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
-# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
-# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
-
-# Here you should add any native library you wish to depend on.
-LOCAL_SHARED_LIBRARIES := \
- libfabricjni \
- libfbjni \
- libfolly_futures \
- libfolly_json \
- libglog \
- libjsi \
- libreact_codegen_rncore \
- libreact_debug \
- libreact_nativemodule_core \
- libreact_render_componentregistry \
- libreact_render_core \
- libreact_render_debug \
- libreact_render_graphics \
- librrc_view \
- libruntimeexecutor \
- libturbomodulejsijni \
- libyoga
-
-LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/example-app/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/example-app/android/app/src/main/jni/MainApplicationModuleProvider.cpp
deleted file mode 100644
index 0ac23cc6..00000000
--- a/example-app/android/app/src/main/jni/MainApplicationModuleProvider.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "MainApplicationModuleProvider.h"
-
-#include
-
-namespace facebook {
-namespace react {
-
-std::shared_ptr MainApplicationModuleProvider(
- const std::string moduleName,
- const JavaTurboModule::InitParams ¶ms) {
- // Here you can provide your own module provider for TurboModules coming from
- // either your application or from external libraries. The approach to follow
- // is similar to the following (for a library called `samplelibrary`:
- //
- // auto module = samplelibrary_ModuleProvider(moduleName, params);
- // if (module != nullptr) {
- // return module;
- // }
- // return rncore_ModuleProvider(moduleName, params);
- return rncore_ModuleProvider(moduleName, params);
-}
-
-} // namespace react
-} // namespace facebook
diff --git a/example-app/android/app/src/main/jni/MainApplicationModuleProvider.h b/example-app/android/app/src/main/jni/MainApplicationModuleProvider.h
deleted file mode 100644
index 0fa43fa6..00000000
--- a/example-app/android/app/src/main/jni/MainApplicationModuleProvider.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include
-#include
-
-#include
-
-namespace facebook {
-namespace react {
-
-std::shared_ptr MainApplicationModuleProvider(
- const std::string moduleName,
- const JavaTurboModule::InitParams ¶ms);
-
-} // namespace react
-} // namespace facebook
diff --git a/example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
deleted file mode 100644
index dbbdc3d1..00000000
--- a/example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "MainApplicationTurboModuleManagerDelegate.h"
-#include "MainApplicationModuleProvider.h"
-
-namespace facebook {
-namespace react {
-
-jni::local_ref
-MainApplicationTurboModuleManagerDelegate::initHybrid(
- jni::alias_ref) {
- return makeCxxInstance();
-}
-
-void MainApplicationTurboModuleManagerDelegate::registerNatives() {
- registerHybrid({
- makeNativeMethod(
- "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
- makeNativeMethod(
- "canCreateTurboModule",
- MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
- });
-}
-
-std::shared_ptr
-MainApplicationTurboModuleManagerDelegate::getTurboModule(
- const std::string name,
- const std::shared_ptr jsInvoker) {
- // Not implemented yet: provide pure-C++ NativeModules here.
- return nullptr;
-}
-
-std::shared_ptr
-MainApplicationTurboModuleManagerDelegate::getTurboModule(
- const std::string name,
- const JavaTurboModule::InitParams ¶ms) {
- return MainApplicationModuleProvider(name, params);
-}
-
-bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
- std::string name) {
- return getTurboModule(name, nullptr) != nullptr ||
- getTurboModule(name, {.moduleName = name}) != nullptr;
-}
-
-} // namespace react
-} // namespace facebook
diff --git a/example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
deleted file mode 100644
index 713892bf..00000000
--- a/example-app/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#include
-#include
-
-#include
-#include
-
-namespace facebook {
-namespace react {
-
-class MainApplicationTurboModuleManagerDelegate
- : public jni::HybridClass<
- MainApplicationTurboModuleManagerDelegate,
- TurboModuleManagerDelegate> {
- public:
- // Adapt it to the package you used for your Java class.
- static constexpr auto kJavaDescriptor =
- "Lcom/exampleapp/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
-
- static jni::local_ref initHybrid(jni::alias_ref);
-
- static void registerNatives();
-
- std::shared_ptr getTurboModule(
- const std::string name,
- const std::shared_ptr jsInvoker) override;
- std::shared_ptr getTurboModule(
- const std::string name,
- const JavaTurboModule::InitParams ¶ms) override;
-
- /**
- * Test-only method. Allows user to verify whether a TurboModule can be
- * created by instances of this class.
- */
- bool canCreateTurboModule(std::string name);
-};
-
-} // namespace react
-} // namespace facebook
diff --git a/example-app/android/app/src/main/jni/MainComponentsRegistry.cpp b/example-app/android/app/src/main/jni/MainComponentsRegistry.cpp
deleted file mode 100644
index 8f7edffd..00000000
--- a/example-app/android/app/src/main/jni/MainComponentsRegistry.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "MainComponentsRegistry.h"
-
-#include
-#include
-#include
-#include
-
-namespace facebook {
-namespace react {
-
-MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
-
-std::shared_ptr
-MainComponentsRegistry::sharedProviderRegistry() {
- auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
-
- // Custom Fabric Components go here. You can register custom
- // components coming from your App or from 3rd party libraries here.
- //
- // providerRegistry->add(concreteComponentDescriptorProvider<
- // AocViewerComponentDescriptor>());
- return providerRegistry;
-}
-
-jni::local_ref
-MainComponentsRegistry::initHybrid(
- jni::alias_ref,
- ComponentFactory *delegate) {
- auto instance = makeCxxInstance(delegate);
-
- auto buildRegistryFunction =
- [](EventDispatcher::Weak const &eventDispatcher,
- ContextContainer::Shared const &contextContainer)
- -> ComponentDescriptorRegistry::Shared {
- auto registry = MainComponentsRegistry::sharedProviderRegistry()
- ->createComponentDescriptorRegistry(
- {eventDispatcher, contextContainer});
-
- auto mutableRegistry =
- std::const_pointer_cast(registry);
-
- mutableRegistry->setFallbackComponentDescriptor(
- std::make_shared(
- ComponentDescriptorParameters{
- eventDispatcher, contextContainer, nullptr}));
-
- return registry;
- };
-
- delegate->buildRegistryFunction = buildRegistryFunction;
- return instance;
-}
-
-void MainComponentsRegistry::registerNatives() {
- registerHybrid({
- makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
- });
-}
-
-} // namespace react
-} // namespace facebook
diff --git a/example-app/android/app/src/main/jni/MainComponentsRegistry.h b/example-app/android/app/src/main/jni/MainComponentsRegistry.h
deleted file mode 100644
index 91615267..00000000
--- a/example-app/android/app/src/main/jni/MainComponentsRegistry.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include
-
-namespace facebook {
-namespace react {
-
-class MainComponentsRegistry
- : public facebook::jni::HybridClass {
- public:
- // Adapt it to the package you used for your Java class.
- constexpr static auto kJavaDescriptor =
- "Lcom/exampleapp/newarchitecture/components/MainComponentsRegistry;";
-
- static void registerNatives();
-
- MainComponentsRegistry(ComponentFactory *delegate);
-
- private:
- static std::shared_ptr
- sharedProviderRegistry();
-
- static jni::local_ref initHybrid(
- jni::alias_ref,
- ComponentFactory *delegate);
-};
-
-} // namespace react
-} // namespace facebook
diff --git a/example-app/android/app/src/main/jni/OnLoad.cpp b/example-app/android/app/src/main/jni/OnLoad.cpp
deleted file mode 100644
index c569b6e8..00000000
--- a/example-app/android/app/src/main/jni/OnLoad.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include
-#include "MainApplicationTurboModuleManagerDelegate.h"
-#include "MainComponentsRegistry.h"
-
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
- return facebook::jni::initialize(vm, [] {
- facebook::react::MainApplicationTurboModuleManagerDelegate::
- registerNatives();
- facebook::react::MainComponentsRegistry::registerNatives();
- });
-}
diff --git a/example-app/android/app/src/main/res/drawable/rn_edit_text_material.xml b/example-app/android/app/src/main/res/drawable/rn_edit_text_material.xml
index f35d9962..73b37e4d 100644
--- a/example-app/android/app/src/main/res/drawable/rn_edit_text_material.xml
+++ b/example-app/android/app/src/main/res/drawable/rn_edit_text_material.xml
@@ -20,7 +20,7 @@
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
- +rtizz9TT7)sYSG9d4JW=e>38R5IMMI80pDEQU|XfgqK_6v=qr)C
z`#Rv3svMbD^Y0?O|TA5O?~1vcEM83TFAp%_p?fr
zoIfF751cY#_iq!X0L)4-LR-~k%`Oj2=`0m`pdd+_?56?==t4&7lfA1;xi-X{{y{2B
z!&`=Opps9b_e$QlF|M~x>2Vc()zW1=Rl<@Y#^iS4R?HOgQ8(bzc9)5Uvke@R941=Q
z`4|JIG8HPWYYl$rPzR-186LzM4#&KN8a$J55$g8<=i1U!B`t~VN>FTo4$dmjQ>Gm;
z90qTasy(=UsPILD6+bQZmUXr38=*H@6CSJww`>z~Imva}$_9;|C+9b+pBbBlp{R45|=vVK|WlVE$>KUNd(}N#37=Y*;iVedL<-V+H}S$U%ky!F-X<3
zIpq*2kUKoRYk;$5r3@?nsZ=8(3+F4_qn`yg}@q@_KtjO+=`-RzEVJNgn#=4^*eO_ZRd3
z8)Lmkji%;}k~kx!`M+M2o}&{p4=WIFL<`)U+rxCmdOI6sX?vh@tE&OQuO1FkBR!x5
zQH5jP1C2M=wYGm4b?_}-BbWirFb6#0%MUaV_TIKv{%g%RUO)sSibmk<`o`!c2iLs>ezef6-*(%aYMauXRrW#U;X+D^|R&q(1oT
zM=n4u!lQo*gt-D&-Yc}=(=Jwv^)AqKHM1Z~dS|9!z`3D13$?d8W6W8D1~vn(N*?kc
zHHoSrP@$#{P^%37MWAptOa*75Hux_*6edwAwpx^gTjAu7l$bjgjjB#*4U%rC=?`*+5IaeMH2N3TCE$o@w{&{NmGBqi{jNhv0hkDc^e*8$Ajx4jPud%S7K*JFaa8@CVF|36H*l_yWICeV0&Wn|GGFZBV-Ah6*q(C80p5
zI_rV~)Bu=V(>hV=-?<+j__3m>ghIcT?;tl-KFT*Js27!c$XYFsT4H5bK6KBIkT0vU
zjrreQ8xbV$9M9pFgs;lC+M(9fh6p(;V^sORf%uZ=BWF^=8ynz@FvnhYR2~?eaBw})
zqAnsDRUogG{nge+J{BaHl*)49uJ_M8goQdx)Dn)X<|hYza&__%IsrM^%bhyWVw
z)P>4r2ed6NDJWncWQG$LK|=tJ6s%J!1*cfca^@NZuK9(`r33?Yz243&qDwmL(vRi3K*{0_i^O)BZGQ?wj9D1)0v~KOmUQ?iPPnZZ(Gh8{
za-YyEFlQ
zq}C3FX1*|7=(ux(k8w^q>_}aTVqJ3{I;iMk_ZrR9woZ^Suv7e{?o4`kV~q`c4J=nS
zu|pZzsSkD>vgwdGhlx6(80?1u8jwtOlypE#r~Zv3tyC55(WqhQoOvK<_#~hZ#cHE)7FVx3_i*w_
zlkZ8Ub7K7^@{%~EtKuu~t%Aj2qM09JRMTttossmedhC~zwdy4oH&N(v~B?CZ=@
zpt=zNTu%9u78pSkX|1n1#1+cbCLdMQ%5MmGWd?#4sG!eg0^|ST&4nJo_|t+1sja7`
z9>Pc#b)QoKEMED)@hOJjpBhXcs^)b_;f0a1GbE+rp!aaKMmopU+o%qr81OV-6P@;Eh3Wqei{%wh
zn5>mgTxM>{pNno>NE-bZ_=Z^gd?bA#>pEc^yz!oWDsMa<dS`*mS;g|vaNH9NTqz2>>(5xd`=3E;Q3dGs~^WW*tDEmLmnkaYM8MEH9n~D09
z(<#d;k$~DKV-^JRI_J#9B+6wW{xH-Fmpus{86$%rYn*lrnLd6NxDmeWHK!A@@({->dOq5U;Zy
zN^!q;evifH=pH_dYZrmJ+K5<1*iZlEZ5as5Sdq0T6_37*f{NH#b8j45YG@oDX&)YkPPdXiBMbMFwYK_+y
z+>b0B#15;EmnIg&{3L!nQ9S?mCVup0Erg;0&Jy-f>JiqXyLPkgtX)kLMuRQN#m2+PzN(feF}
zdfsA9hq!Lgu9#D#9d?wvZ2^U+AL7
znw7kby}2o<{=@2KD?haB7hwzP&a)@?8gq2)jL$u_qFh1>8Jl}
zODDeyGS|wW9ahaXw|=RsoaN^1$Q5qz_dAM59J;J&OL$bQ82mVE;q|tyR=B}q*dfG?
z)bag;l!OfA8q5VL1U(MvsdnRfAhIREX=m+v%d`tv>8#LzqXoJiX<
zbIS-Sgap#C&&kTPIxkIWzsp$VYmpteF#hT7g-chx4}?7*Cw-UaG%@#GCZp2w4vkd5jn1Do#&O7i*4K`z6E{7&
z_EvdcJ95qGHQD9-7|R%#B&2BRtI~V6=ayG%ES`p+;EsXBKu-6-A3S)_1X==njeK0%
zzab@V>c)3DC!I_j-FOr$OA+eXXdoDwnxkiTa7{x#o=LO3vu4k-M*Xv@S&L`O9+#bw
z8kowh#PK^hnVt&;MQe_;dAGzdQx25EUYcxehxB5|@ZE?4XW%F%Coqn?ERz(aoYH(o
ziXsG9R9Sk;pIF6x|979C-I(j;f^jF?YuDX_K4U0gp+km@jP7w&<7!uj{3
zE8pkz#Ou`bh0axfKr`ihbkln;cyq3g~St~-|q@Vfdn#7f`+BP9?2Rpx7lMAil
z3|I8PRUf{VmzQ%DSo@!=1zHA}HKw#sM&*=~KXz4^Eu#hr;}5u_KWve)@aqrIK3ADZ
z`ZxhZ#W#XzZ0SjpG1v`~!_<4@j;K0vkF9{2nOP&yWFYPWSv|D2sY=OHl$}Ysd?THl
zAK4xHssF;!)VJivu#mHKq;^ThXw^{H*bWfW;~EyVYCwy?*3M3Fa^bk?=|@3cUVqW7
zA@~8f5wL)Q6s3w~s2k3d5-OZsq*?UTM>lP!Q{HL}wi`>6DO5~OCKvAfqOcKUmtMwE
z3LJ6by?u`8%o(LhMVJ2$6Q`(OiO(X-EMwodq^ki7WIT{f-byO|ln{x&XDzc7#oVK+
z*VYPWXXN_DLMclLt5?uj@O1M1^pz3om-@Wg<%-tJhtS=U1t-nXKbvb$7&MY
z`TXiSOrQP%-y4(($c-&^n!KpFju+)6RyavO=h|oaWCSb8U*#QlDLEHMdu)-wSSKpC
z)V&3DQRXkstht4pvCXqbEIEDeV7Yxw$UUQ5*xRKMUVK$(%NA4h;XaB-)7SLKSirq#
z&GeY;t((>_I}Zokv&k6^Hh<}r7^6$_^0GAR&Fhzd%8Q&~=GIwJeqEN)Gfa#1kXZ^X
zb57h(Nk2>gnhH$+nPgvM-ymJv)U;s!17#h`T^=kx9DwfG@GyVrMl-BcnVj@@o}8M}
z6f<2ZfN$`7^Qwi2TVKtLeOGz+?!(;ad)lO$p(Jc&X1QbCeM)HP-wPCfdceIG3Qjfl
zl9jtlAbz0DgpZG}MIL=h@2G9UvD`r%cQ9fYb_#50i>-15p6_`SOn!Tde`0DX|MTaT
zFGRl+9ByxZ3h=j=-cj;wA)6meBzy~PQ+9Wc
z0gcNN@@8hwO76WCa>(;J1bqAZdpI2aOOAEn-OSA6?TNZ=qQg_gR)ySwaZ>jFKA0?7
z_2^O7?(PG==7YU$(6&1^>Cc4B%*=Jkfb*1c3;Blweh)(e9L%uZN;($##*Aj(W@vMk
z=Ii(Gi@-a=%xLY3_V%^#?3a(+E@(#TOhyVflkyGkz5NOW3{Hi<2V-y7u(p2us3}`M
zF8=4s)+eX@!TICtZ1xkjkW$C?mp!76p&exmBqM6h@qK&Yhigg+e=*->zK(RY)9oSe
zZm=Ts)|EWV9?M9q?2$Y?+MfQzALu~+#D<}D6az05KfEFJYI3qf>w<^x!fb11lH#YI
z1;}V<=$SV~WNq;#m(8!`;az1!(Th=rt}qk&cIcH&`ykqh+{$%l=5zCcK^!6?;FiF*
zwo47SISH=<#y@}tH+0B6$0vpky5zB#QX%$@WqxsbfyTBJ_-=(-tc$W=>U^Fm&P@n
zKt8V~T!gPnGvCz$!aZniHDN!bkNiW<950PZQC*qBL@HDV%2Wq-ja6aJLZeBVT#GMJ
z(-E2F_|d4OF2vRsLUuYFtuI&MmRp$s4#=gC8v*axB?#M^3gm7Sb0_Bg%Ml5l^23M?
zs5g)334&Ps`^o|qVDiSJD#YUHvZD02%uY4yQx~2~q%SOOGp|T(nX$cUQQpSrXiH@B
zJ+pJADX|p!`zLwJ7i7X7Bi@$2*oVmQ?|#CEc#cWf0NKfONzGeV^g1h|e&?`Z0V|?_
zwfU%1dP}A3dU~gETQ+i8<1-
zM?C_1B^k_J86W>XqIKt2o~DTD3^{vCnUIxkG%olo{JD+or2cThx>5Aaz&Hr$16KrS
zKve#|d8X!?+XGC3_{v#oYi65tN2$rX!_RL-t%{nO#3b>SV}P8(xB{I89lZxc2la~3
z*58=YwKJK?<6^XjLW>|ZvX0@Cz1fliO|(y6CgZonee@zPm9!)PJ#aE-GgsndV&p#(En4ZhXsq{U`yh~UG3qY|JFEmsVtSI8K?>8*_OmZ#;
z5VxL}l~$UX97%n7vujK>V3=5-`7t2~0LQ{6?Qng%4!5626A!meLle=gCN%;9?|GUsOw;o)tt0rI%ZF?F_-hOi^K*1Tori
z89%|YteaE3y9ylaxW-yhet6zLBfCLcB5a56$H&dO$C~;wGmzRLU1LoG<;}=NG4GQp
z`r}SShUp4^WbX!c;ptv6wl8)NsIGkuHEQa0Lt_%EDpVrMkR&It;o+UJNx$8
z(IuVdmQSUUV)O>=*pK*x$4}B$C3;%!bbF2W<2N7u3g^_LrXSa
z68&~3TO@%k1#aXk-&7_IC&_?i1hfPP)*ZE}(TQEcS_~58RN}?t@$Z;QL0Y`XmgeNk
zSE%i}YUrpYtO|QB8_iOaKa_zHu2PM{HXcZKGN0AO%$PmU_PdnwGNkMpHbjFHbDOcQ
zW>a<@WK5Y1GEaZL@J7AJA?IQUZ&fK(hOP1dwnbXoysNpO(Q`oza9Sz}FS4b@G^di3
z5RA&l+&;gufjDh0jCr32c~1K%e?I}e*nr6(2*56JwRCmy;RFj1UBWWGu7MijZ;tp}yubFwqgJ_}
zvg;44PRxv59PO5TBex}si3b6lqd^(e!?eRDKjo?%hZrR$F(o1~d|OvIx>li1`Kb$d
z;{h1j6jgg1*&$M3mz=ndnoXP2+c~3KguLex`+ip1bmlwf6s?#G*&C4LdDk`CKIhOw
zT$XrV0qD|uLu1fIkStp-x6=0kV-?mVy4X;r&wNL9$!s`Fkb}7hd~&3$g4?ySBEJ+;
zbNpQ36|ZRbsH)^V!dUXl&bj6Ef)TZz3zz2F#mrO=owEC@_~8++t^XSl^l0k2HNe#8
zFp>VlUuXc8yCPxwkno?ttS)B`@@bS=2<_s&c%1o{>jKv>s2bu#J%nMS#t~bPFVtm1
zDfl+zmv-I(t{vox87WR`mbufQD(qfIp0-hZAmE3_khkipl^HA7yGxr2Ml=8fI=3v+
zp+(P1rO82$1I$$*<*2II2_bW|aN$lY7aVwcQjK%T(+t1>qHImJ$+c^dS5NQ*R{*g5
zuew#riwE+CYFV4nK1zJ4g`}>~PA7^uNQx;l&wt8~N*kdw?}Exyf|*$XxpmAKiy2
z9)7kerUvYWn_ggEfh;Pmxj7BfMSPSFtrdxM$XoNIA>V^z^+esM#r!Yi+OZZ*JZKw>?w)~91fFR){z=*`t!y0x*3=5_X(|e8rv{s+L
zvhe0-=#@%WSDF5XlN())jUmH}LOx0j_>e1F^qzk5N5}C<^F>+eoeCG?5vV=C&$ENL
zn1&tR+s`iCN8K2q4!>YUR3IOMdd}6c=9GF|II9^8r=Homq5~W^jcV8l^7VKtorESv
zF?S3>LW#h;5-lHp3MqS&RsH_@!tYYeCKc=HWyZjNn11l_^mQTDv_{3*wDl8fn`Q;p
zM|vh;YegCCF`x?auAtd(*#;IfV7%MY5-HREYs@Qhi+|%wPiQJy$6L_<5VD{yunSL~
zzqB9UB&JWruI*{+DD+H-tQGCi)J<2qq_!l+bEyGr2TguF&uli!pg{54&5VwqvWagA
zK||73$Zz(POG3bNrhAxi81hI}SqakR}JRu$%|Y;9)kQ5X%<8|
z$Ya0qtU@^MVbOF_hrP}p{SITGYmvy$Q;wpAG^ruLsc8eIOui$b$PUEMTY=w~0NsF5
z=Yp=TjxAM(Or?&;LM!*E2Y@SqxOt(4L4XhpzehZ?rHaX=8SCnkTfk%N-~5G6C3us@cV`m1
zmp<@_-H8qHN6JP++mq&atBhlfAD40;qW`EX3r!imT^5S?0WU=0Jzco(^KbERT-P?Q
z`_7TD!_rwho&8h*JpK8CjR}(j%?S?AS7~83sj+Maj2X%hZEA^F@xVN%{JMiw?+%sp
z*0#!NJC=P;pwh1FVbY9jf#5LwGa-gw-J}Wnr;eoz3Z
z0FO|YvuW(nuC7BkL;-Xo-y^A;wH1
z$KGUo<+cUWZ#oMCWG`*NGmpDW4XbJegb`@Ho@Jzr9i#oA34js+2_k;OfMTdk|B*}h
zOsIywq8+9^7A`*!Munn>=+`OXCNh>3#uQTdo$)fod>dEA)a?d9cI1+m0CJn8JnGOqFWN&B9Z)il7q
z%ve!$Ul)AM?KPww(!SA!;(1keU!BNHa5IVINYNfctD!wVN#2I*hsL??L!Xy*$jn0L
zmg8{&!bFLCX@U6i60n@_lY7_<^myVh{GCuG_#COqlYWTF)k0Rm
z!ScwGB0iuM=r?fesr(w^)>zqH!YSImHRZODb?J{sQ6S%a3v?gZL}nR5>!H_u`4_$#Hg4Ye-bXw#^b{fv^JS>syGm{7c*q{9soz?e-*@U6IL2RX@5Oeg(
zqW+F=0me%tZ}4#}SiMs662}{sH4L>)vlOivcCWgmx~M8^*wD)Ow{NUviIO>c}Pjv&!G41=eu
KpUXO@geCyPqIRYL
literal 7179
zcmb_h`9GBH_n+NhvTu`Znh+AhBs@xFm)%H~WNXw!q-@z{Ms~@TW~gX0Xd5X@wi{(B
zOV1M-*~XHdY8X_OCi&idzMt=Z@cm(CuGjhD-1jxtIp@7xS+35uJ4AMhKp>DE_I6h8
z;BWq)4;lr2f3lfvgg_MkvA41y#X%Q4L>V`tlm1=d^A8ubs+EZb*qisk$}-28lLOn=
za_}akM<}V~S|MjG5q-3XjI->0iKc2lpO@O%Gchd^O-RZa*}}~0drI7^qvBJRmK>u_
z$DPs06n+*^*g7=W(q2@w{QX8xhT{QKQ`6=^GgWP^?5H<)H5=$6S$8IwZpF>CKMO5z
zaqZ8--tF1uILS`tqnwS~IYZg`s%ov&yOougywXwwV+!Rp_y02>W!tMiX(;Qdt~vQ7JyDg(d*M8SDm#jsaPNCMuPE)c<8Y3>%=>dp4joIy%}GvTrl-ce#0Gsxn4Nqth?{K2ZL&Oo44}
zSU2VPp0=ff{>L;<)Gi9*v3LWvM2dVv^{}Xfq3VSa4^`JXnSq2Q4n`cF6eYKyyT*^hPCR?KJx%?o;Xn!mqltNt!3eANT(RDVT>y
zq%;4L)P**oj1}Tkcm@H_*FRg-0D|EhAi9QG);}K>ke2Buys9
z%NKm2?q4osCi$zKZ(kP`afD2rTwV5QC!z_SNK_
zKY#wbE|at39)RZAXih01l#?9Ir&ywZ_6Sd$st36)j=?0Iifd&18;*06DEao9eQNhg
znc@fibh`bmUi9;Vr&x84uqoD0>RD2qICOfiOtvZ{!NKrC$@*s}M+18e>L
ztkt(iap#wEh7rG4=al>6EwW7=dVqYc9!<#PMDDCyZAnl2KC)Kip7!
z52n07=U3D1+rOqie(PEU-qkR#CY1a4s1=4txefew;eG|2xx24i+2KJGv$1&oH8N5a
z=8STNoRPeJ>x302{IuqfqO+9bZ#~H#UCWv=dEgc*zVqS6H{9tI=9U_M|Nh}e1D`Us
zB^$-(ZEKiA3FU29?D2hS6))UyZO}%MI4JKT|J{(S+mhp2DrI!MUn)g6NEL1(W(Pz4
zlH;*(iUS->m~`!;2kU??BHkq>W%~r#K$NjN$d;}Hk)!Jf4NBX~km`mQD;0LX^4G(+
z`;wQ}!1o5@rdLU%O1#QT4kZHfM-Qm#|W&T8=GYu}m6QNC>gm@J=G8%dYROG6&AaDIn-Qg
zmSwR-@7z75H(`%$i7>(mJ%k;rCWk^oA@b02M1!N@H;Krb>z`9X5nvVHDfPxY6>C%q
zLpP=i>+~TiOE-_QA5cSa{oWtJxpl{q~>E5
zL6VXCdQAXq4fBb4V%_?pB`i_76BrHAC>WO#ui{aI5iA*Q)ncGO;Q
zs*74N#8wfzhsVcb!<5FceIY?z!_`;T-F!aec3rx3=^LPxWff%1beuSL^5lAX?v+>=
zAMu`mN>5*n0DCRPTStxsxoTu+7#@=s3*R;u-r7oiBa+q$`!rurS$Ss2ASgzmw-2x+
z*-3G1(lXgy7%NUU8iT>ylIV#+E&BxrZ#k^(%3D-UO-)q|y{hVX)2H3}rGEMp>N|8?
z0siAh^!S%Avo7o3zw1GN_i(x9wY9Y~*YQuUNbOYodhYXQEkCKAm~H^zJ^;JWg@|_-
z!obF>@`jRv?jnA{w7H1h)iM@bjv*lbc4&Yjo^CF(aV7g5*m=6%K=^xp|bNg*Q=8qTo=ty6UxB*^z@$(tS|Sy
zHnFv|-0}(78<{~_P;gjoYaQx;3>TA|G0=e6UITFj)x^pDWIdnkfbJSZG$v4OxD!_R
z+H3Z@1^JJFCiC6Bt%00t6$r^Cqq%ru(|$~|*zMO!o_plsL~2=U#6DNL-K;ye6$qbV
zy}v*Or;5sPVI{p;-TMgsJEWu_8%?y9l6OC4U!#d>{z`R$w@U{as#lT4kehfABK+Pc
zcq~dq4v_2ZtUg$j3IsxVC^5GIC9yF5I$gMO`ciwsSfSO7@O0Rf+T_0o#8h>z&7B`l5C|xuy
zNYakpqRhbKc|id+rJE|fty8Q^3UG_J?;n(I!g}F=JoODnl>aWZW{eLT%~o@Us@!!b
zBwf>iX9L>c-?P+^nkcfdqqi%UM&LPSs)2wk7m|lHwc=S21;U&Q_@(=mm6g_bou$v8
zTTyWtOy#}!oPqiMlHS68tkTV=-YZMEe>L6PGN?nTi9XN2f-u|g)T>@(UOV3fa@7so
zhZ?3i6vl$N#Ft+xkg}RM3Gtw{ueBLgItFqMdA*zz*MTJqtzjjXR?H^5w)bR5=}RP(
zFF_B$6lnqykx2cB^P*4a79QM-X&%}^uisbPA-JfNKAEz6HW{+y&ZVq%3clymjIpR5
zT?8T#Bq~)f+aHN&hRDGq!ZnjSfK4C=IP9)5vZE)fkwq&4mJq(&q@M@)?+)eWuYbNd
z#fl)_m2HF{SDQ_K^kT;NHTf{YA7OGB)2yhqC>c*{rq5O@uxy#`m~Ry}6?wCTOB87{8W4EF#%_Se^BRl*7~K
zRGQ9hFjd8ekLG5O7D$@B)}l@YdKGdC-PP}xZ%g}&eSeCjO3sZdPgV%iaur%Vu0URJ
zM-f#J*?@O3DHk{Z<%@Ue+R7T&0R02V1^S_xq>Nhmn#n6b5Z9aUYeaMai&~;UKpO+1
z`0u`ALHaP7x=%<#&bMZ!TzEZtJ4%p*3+A+>v?O5(RTm=%%cC
zUjhva_`JpyHcA{vOngrI5~vN%;V$3=fR}8_f6DO*K=meQE_zXUQ3pM_Re54-t`3FP
zyr6D91@#f$MQ#qj?{Cb`&hdh@!YQ>5vF!myCQPaRxV%Gufd><<16c($986Ud
zWb{uBhhZZ%IbL+!^Hh;SQ+8URloJq$KRBeBWk=*%hh15JWQyH0#Y(UW+rjNHBs$=KMQ|gD
zrJDQpbdGlsiUMw!bTjSls4$TA*ZvU`Dg?+j19H%yZWo16@|v`Hf0*Rm>+nKgrZ{Ar
z>Wv>J4l2#*;>S_2}Xs-~4;LTbHclV86PPJIi3^
z5_^m!oje(#z;^6OtL}vhhamW^~q^-+uGwTxB|Ng({P_TVoOsRU`jP?$(ovK
z%bDXWjEwHld-5cLur>`N`dG(Z-r8?$tht#u6LE7lg+h6eY81Oa62>ky`g_zU(y#Wo
zUx}Ss8!_A`cu&Hghz}S!c*1Az(
z!d*2wJLU5Ek}wcH?9;5=9?LV{{qs*tp-~n26WmKa=hfqql7(x$G)jzcq{VI5xTp8;
zZ;rQQX}-QGeDM!T%{x_*w-pHyr>h#ZuTho)4_mt}$w;p5+c&Ux%q5V))Wx67nKS<1
zl#ML=c4Go_|NquZsM`+J*S1+A$1`jn1>y)o7V%+Abo)?9oMFC78OlOx>TKTjrQ
z2H$v9`{QZZezy-|F-55gtx5zW58cf~^C6Ygu)yIEx#qDLhq6K4^I@(3Iifseb4(0c
zee6I?U6+D-U1QFnsR3hRUGUf|ou#1fV!`r6|J!P&3Yj;9h35M82m5Dt1(^0KIS`5-
znX4EVx)tq#N*BD!B}#f@7?}tA{#8cK(;gM8WkAOV!ZObBxPdLmm3Rhmkp%;vrxJc1?oaTYXk#5r
zbD5_73oBy>L(?2Lu)q5oZ7(x{_*_MAT~HwD74)g^AODmiCj!-e(6{O
z+lHDOwuKVuq)^@`N&*%iD&Wy8^+7pYzIRDw3|U$
zg9F-JS>oUhI?~#v&rvQjALTojL}9eLF3RK=(e?pyHGms(iWS6_$9>!N_mMN=Q2cC(
zTRP4z9Au=u@UxzEq53v|-sLRqAjcM*QE3L5jV=(_s)V|F9%_O1Xx&WK1DW^5TL|6j
z?m);Hh3moIc!Hn-vh7gdH-aPf@YukFO8O)bt3L7=WaFmP5kQQ6c*SfBbINs*f-r-&
zpdYfHy@Ti%MU%4bI`s2c=7%Fu>IjPjDDParfyN7(MPRCaW9Wu_e!IkZMN;#&dvq7Z
z#?Fv<;<sffufsSjnG!z7L@76Hy
zwz{4V2T%qjGxZdH)jt1f*7Er^g{8&Cy)gUy9BU~L
zPM4MA08b^rQ{veV0~@PGw6Vy>o%KiUEQDkUT$t-$qiHY8e04QP%^x=CHSqiSdbP#c
zk|L0XJ4sqh?iJK~Vd3B)r;d9z^C6`J$JOwQz(k0_7);4sQ>GmHhUtAB?Lz-Zub5P@
ztYKPOv>{qBQF}q&_QhgQsGiX`M{+CF7NM^Nj_^(ZP646tb+$a1k3>vCuHt$dsC5dK
zQw>-)mea2Yj$sjYBRI7TwEG>~v_Mlx9jtU$IyN*X(l|02bU3Q|K75>G$M=
z;T0)*MYtlz1Q_n<_!WI#iRdjWf;1u!o`H<$hBTr&9OU{;jm{syS74tbBu^M5@uO5l
z+HPDeJ!#o&i^y)zo{Mvch}bT#I>+c%yZa*0CuN)KbY7|MjqDUFx!bHyp1PZ=*y_?c
zh~P4C{n-t0EcXeiPHWA+O$!eSD5#*|OZOQ^sTxHVZ3}IzRbY1zm6)33I&hEnhL+2m
z7)0y>rG@h=j-a2Rh5xERqtQC%GBQNv;X}^lW4boFKJO?^Usd(fBR^aQQ&W1y1wnb@{$z-ih{
zT)Ahg;y3d4?ef9kxqyJ3gbaOxG2?KhtEO(KQPY#!+S}rBMuZG06e@iX>0>?5S5#Dt
z0+eiCib2mn7F>57L0Y?=Gx?*+HpyV0jziXD>`Y&(uC#?KCxAFbq~+Z-O-WI9Y{G10
zW0UZH^GRQJy_T_V@}Rx~vF*B>#t3hWJfYROKLCkIN$So`of2BhDk<50_?3SZsMZgP
zyhkos@qLA`w>4kyLp%oI)vQe9ydz
zRAWmX7sgm5>NdV>b%{8IAQ>qkvU;fT0p;sv&r5{0`w*Z5;akHT!+E7{9gpsk;`^oy
zf!hSALZrH@;8QkrmQUm>dJ@;ElcHHE-`YkL;59d4tIl>h@Ikm3F*qahg!sy6OT=^^
zy80Z*|Uis#_X=tc=p$LLX`
zYsl~E4>LBr`QtH9RY}dE5I$-X$CkOL90|w~1@z3sal!YqJfV^PFt#C33wU)rK1Dxj
z&=EgPu9@_rVrYKICHoQH=PA~$(910mTZfj7Y7~FV&5FZRg-m4UDO^fq{76_xw~gch
z_&8Ai>Dy*3{aFp!3<>&O!QBP;ddNLwRq)kOKn0<4d3GqZBABstuk;Wq4#N)%H
z#}a6B*#m+D@W*ZgEh4LiT+qI3;_c!4X3%z2c3>Bg4sR#ce5H?7b
zmR-`h^z}!UfFAAS(;Nzm>WGYO#MW7dkb{G}5~yi#cxo(jOsrr-mOV}T4w^{Cef>>yvCGHu30#6M7lj;O$#AMy^
zlRSNCwAuYEHn?VtwEyi!hId28>V`=*d{uUi3
zok`I+(`|wqh1)`ypwA%q@}=;buTLH}q|m{jPrXRkuxML1=sILHv-c2rC7aMcrPE2_
zdsvbRD3ws-amU9pGYZ^j_7HPyF*@2KPpE82tpqfi5s%`z$3}STw7pi13XMXI_J)EJ
zY|kmy$q=P#avrKA^@g~T7!T4cJnP#Uk#gn49nGGQ>+_J=q%Y9{X_PfNZV>k!@Eqq=
zO)iHeAmT9D+e=9q`spN74>68Uwt`|u?=hvk?rz+vB0w@ZX7l!{b^n5Z^VC)J*mPKwkcIU=in9UtOy-%6V2P!{C!
zHQ1I^6Wjn0Xs+Cx1@#5m#2*spSQhzH9lqv;4VgGQKIFH`M#4xgd;!*zdXc)1P!x|Z
zgiQ$B{)#``+(;pZ9+5`+lCcxN9bt4|51}FfcG2*1w`-#=yX+
zL;s)cAbfJ;^JNkP!}Sz>ol6$?7{By{5SPE(FYNBF?cXnt*(m?~dEirFPT@{cCs$@-
zM8t{AclTKlC&PP~#Gh4)qff_h3q8Co`cC@BwJ@X>TA)q)G0zv4@Zy9>A4VUy|57Bv
zv~)!NBE<6KeJGguloPt~IjH)FM(B9MMC1PK&KGshox6V1yF0wtm5!Nr?s_j~1
zm7}+ve0^gU(aTHyhxWP#0_)oEUu>SmyST)em30Tcy{YPcdRAU>DyN`evEydrITQ+|
za^|{=SM_k^085sGmgtNqk^B@^Q
z9v^xcF7OwNaJObH>lX&wZmHTh7Y%Via@#8o8b8f)L5?P{z){O($Altj!&k$Z(BwYD
z@WTry7S7ScY3j7y?(5;FGj|T!$y2dR9Y^={77Du0huvXNB=}>xk1TM|IB(ox-g^-K
z>cH=VdmalPnc~%U>?+;AaV>OqpJCo)>|*ym`%#fGE6gnr%k=XI?LUV91ZfYL9weyw
z!DU;jG|dIu@H>nGwO+pAyG)x0LW$?Uh5yIA_c8ne>u)CNoNwJ|LjdDPuHd6I?l7TB
z)<%ZlGqewLZx8%Fv+$AOzmv4h+R)pcL!auV7=Gi+Q{($kh72imI
z?%hq+Lgqqd*SgVMZl>cbp@;T(X(txOYNb*W)Z#vOb2DCG>o`hP&px1eFqm_%xqFl8
zKjy!>bCHTul7Yf|Y&68h+R=&t=FNketigd>G}DEv
z;r|Kj@lKTy>P!q7_b@bkcbe72hR}l0!WxVxlo{!yVW~JpX=3@wLZe(fOb)7&4!?0g
zlliCbLJ?!T)uX6{ot8?*B8E_2@4CwS6^uoUng@QKqXjMqOvU-snY=%+P#S*K$(noY
zKq$wa?80=|jRQ@!CXoq#W^&!7VMUA(1ta^Cv?9j;4%5gNk9t(vRi@Dz;8((#Y7UAt
z_l1G58wY=TRMrvdNT2$;-NK~nD$}scp+b9?yOo&!)0oOzbxQ2Jz!J)J?;ts-qmZSG
zEf~3{6n>#6$XRhJua4uVI?Ys`dRK$_=h20Lu>Y9ey$-smIQ8rY3oYRyJ2@A1{J?L%
zg;U*Ybt3TzJGJxNKY3}YnQA!(-8GE=DZ}%}YDHobb{?Y^u7|;Uxb;nR7csp$_;c-I
zyxDsfazVh3nzXIBT~t>2Pj_3x|IqrjGj5ZS*s1atEWx=Vs>*{uHAf?UoKhQmHLg
zcb2Uero&5XE4L|>?guPCC22=0r_ojc+tv%@ZgZ=t@7w$|mxTtannkCTPQJav3nB2?
zuKU6T7EP|7hXoFLEME?L#WWw|V*F^A@xg(gYyyf?p05rBbCPpS6lt^F4;X&pOR~v#
z?+d~Y_v_@T`0iKSKP47EDo1fnP|q$Xh3`69PYvD=f5lRW=V&!5y}_Uv;bI+N&JcQh
zZ#V40Fh3zjk&)Kk9aAe$4b^1sIJ|dB)S08j=utECE7lHHa=pmkF=5i-|MBnrhgsvC
zSUewgfps44z)jWYE@J-JbJh*>Unp{qqc+UN`q3>$*e`wg_~`BRiEhDKc@MiThTvS^
zVeilou08oom&94O@G%0H&}gX=Q_<`C%Cs&0g@pW5(c5d>VcdA@DgAvkjWu5)dixne
zu+W~SJUPg&i+fMy+5!rl&wT`DtidXCr$ysXu+R%{lF(?^Ia*D)8w~uVI`dDD$D=~7
znAy+W$CB*I=3dIM8kgqlz2
zYrzGA?ztS7$5l_nJB=o&8n-GKpL!~@DpGjhH^W}&DBJGph{9;H64S>4=J#`Rh*81C
z!O>BXwYR@RBeq|>z4`X$OU#}3>s;&pG5dR(3kluaz6V>Pw7P}9o?Ylu4?`2LVL770
zwk6}8>g6Taf-@xY`3NYFT-T+25fXAVK~n!pD*u=-0Tr_?Zfw4U>G89-n_grLM&4w&
z&>!i0{d(3}X3fLFsjM&S>hw|4m6h^N#Kn$xb8|Qhr?p+a;KyBzl79gA^VxONnlV$k
zBN!#FEo_o@JAAZ$?MG9bVcThrZ5UWTe`eVPV?!d6zI^@lH==q&OwuN3u$)4tyeSZgFZvPse7~y0jIlFawV&pj_M1c^DjU9ZcHd$AFWY?C=SL{Z9!t
zr9=paR6#~^9@LKR6T>0(b6uUSN%m|tyc^nBQ*1qFcsjm!nh(!eO^w~$=jUMTce+?-
zCCbKx8gML-JV@Hwsf=`gGCaQAc>*e{dD~T`UI_JaS&8MbBx;9PA(#tGQrjt()m96+FA>D4_4|?&dKIaM#
zXeRoV*UL}zILeH;=D9W)qon5^v9(ki)>%Ea;*`lSfLShFb0Q+T3eg9XC<~aRi`~>K
znJ&V*b{~pJq
z6f$Lv@l}%Ft*0_iXKwr6dzabcIQVO?%dpI1d}gLT-9YzY_W-hw%2xUsDG{Z0@d?kh
zs!<%Tvc6Mri`^F_Ja0uAg6Uz$N(NkqV{1yr>zQHeT
z?S+WkvwuQ`I!iN(@cg1iH|%5kLh;`cdG0D`78^Wo`}<99U2I?{49*eleE)vYEx+jR-_Nc1AP_x4UkaHtxqo6F#gQpHAG!zX
zMDpaxFF$My&pSjo)Qok$d6WKP(zVen=g8RhGTT~|a|oofrrUQm5z)#4c;XYAg114PQm0P2=tR1o
z5N8P=+uC9>G~B-1uEE8X``#-+lAPWF{CIW5(?4L>#law5lx?R^CAVVe}vZ!c?Wt)ooAxXQy{D8#n6Q~}_PStrK_v?39Rh2!=*_<)Yp1k}U
z)0$~-6f5<2@JC8-)CmE>HK6BhuRbO(q9yO3kv_kE7`wU}*tOI?FE%qxaxBQc!PJ$(
zx9qc}$*7*F=1)L1baq~T_Erm)SCnRLWAoUuVgYlIy4YIX*V~)_W(4bg+V;za2v0O3
z@Pk*;TG0dj&pUD_PbSttZU;+T2Tw#v6JN-&vKre|RXeoQ%IpLkrt16@rzwRQn}m^v
zegr;_R6A{*Nr2HGj1apViNbTj0)Xlupf1;vMv;9#f1(;~qJI542*Ch>dL>n|zOJr+
z5trc88mZ=g0%+&)MV6NQ{0D5o{2mZCGVzVmM`O!VrI}zC9ugGz8giVvd^V|XYfIeM
zSFNeZAI6n3z5eaf&Ou%l&2lTsj_JZ~_yyb>JCo5dT%s<&?(N&R-+uZxa#~h^d1}fs
zJ4Y6;5!$s`*F|4a%2bs?bYCn2>w@8&`S79i8XGNy+v9d9*B&3~jkk&>r+UOr$qPAv
zlbVqAT>o<#TSR3@o?BDRnmuofgs68%Ml%CvXXkq%&`8Lwwhx*&_TMMGzujbtt*pCu
za1V`l#RwJk1euSkx_~yLPTxtDEK4?*JF@e6($CUTK$+xdd=Sqms3=d^`Fsu*dPqOj
zqWZ?Gq1Dx-68CsDfg;=+PRecru<}Rp@#59?vyOLadZ-7&$A0|C1(c~AvXDCxxHaTg
zHto?dKkuLoSBS
z;>DgYJ_V8ZE3^ne&5=hRH9)k@b$#wW=#6C3@Oiy$7vIlRY?k8Fs#9mxP2d#oeeR9w
zuZ?J_1Ua1XFNNVR3L{gRyyJ
zj7~ozr&Hz0s$>=Y38G9qk_#AA?4tLJKAfa`?v@_B#hn_l`}YrXL|t56mHYb^_F?zh
zOa6odg~3}YN}YETyqd?Zw0~Iqv6E-l>Vuf}s}*@K9agkz>>aqB8CLW<$WcGlXZ?Nj
zx1bO)NLQ0PJ8H@#Z()lJczMWuCZ#duK1$Wpf8H3y<>aKMlU-nx!2MbdEh2>QuaOZ{
zEuK9(Db6c5$aIOs=>XrEK6Uv?%SOtA+eo;1xKg8<
zC{~l@Vo)(zJo(w+2~X`yi&D#qa+qu)Q5mKt&bGN}=HmtD=hH_A6O_81-w7nQwNyv!
zblWXRgBFzV3H0UYeuURZhE?_V)ZYIUp4{-#V)~F^<_g;*^V|~1`*#C&FM`TROI9Y~G9PKW_gqC!(Mx3ha$^-hp6
zQCVG4y!ZWk4)Le3qKj6qE~I-*d;J3&P=LO0?;bJ#cLcqRXz4h6ob{H~Zib}nbj`=-
z)6_#}$>eQ7;vs}c7SNWN+e5JTP5BQ6EMk%@D^96gxNy15LPrOa@K7{)W#vR>rog9N
zR#jo++!4T4xn&*G*CTne_07|cfq{j8NWh{p55n?#RzI?DbW~HKbN(V7g)>eH66{&2
z;eUrcVlJZ4M{yzA?*{C63h7UfudD=GT4wSfL|C!Kv+H%Ot$mI>K4&g1z{=yjs^ixJ
z^99AVTJ4_NDc04edf$7uyzp2bska=3d!2aH78qu$Hx6QqSG-rB4*}Vr)zi(bCZ<>F*_WY8Q{dLRCWwuA!kl?&FZZ^yyF5W8u
zw&d;(@AFVOTB7&tN?^6Tf&v<*qWuFdp!rEe&$U6Ag{|I0N~RUqyMBK9!5`P2{{hPv
zu5InJJV}i<$Gqm}mdA_L0O`64SqhoEUTgaV-n{^3#~*YBnCpm&ItvrE!X|BuJ&VCO
zdw5)(P(9)Rsng0P7vjs2h|9$!_08EO-fGlp|KQ@`k%cA>dYqmeU;lR3#l>`WZOtOd
z`=L%G#L)?I`mbNwdcujP3k7TI>%(FlKTJPjy0IkIst!`zt#;!Rt#$}xa^U1=c@K}1
zv24-`oDu+jK%!6xAG_(dumCwlH5JNw*-j)Rh*b-@Q?STQ&AY0w8Ld*E`)seCj)_rd
z4Gv5crJdFP6KRC}n-!CYr1dXf5G;y2KTuO48qDg4e;(lOq21Jc=yw%zTw-{CX;k
z$LQ;)dP8g-J!%Un*`dthuZru_*0$|o)HbVtwKgt6rD~ua4sXrMUMvH7B9R1ucBV?o
zN)I9Xe*6%I1QJ^g#8Kg?OmADwBL+W_hl`89ctouNGD>9ON?u)d2>`YqKXlc{j+k6~
zbz$NA+KnYzt!|-mG*GM7pq+S-Rh6v3PgaJcr-2|N@SK4#e}xZzp9A`uwj3w|aoJM+
z43$91K6>V~{scd@kY!Ko&vQhl?91e4XZPQ)e-lC=6z%DvsT=eo7q@K(t@kh>V+VYY
zcGbZ(Fc9uL1<(&Hj_G<$wFd~_JAe+0QAbtt6f82*Af>h3b;l;5A!cUg=cgsCcK?k~
zXX)z;yg>7+Y`@ib?#ucywzDTs9)bnW=f}FZt%dy=PI|}p@4|3LbH%J$k%HK3@FGC8
zAmj!OC(^SV-a7{b9LKIahi?IPBsVt)h*nv$QVZt~cNDQY-@}aIK4AHE=Q>)8mo4NP
zVDpHI=d)m4@c6X#b$g2p1U{0Sb-nf8S0+fQi7^z6T}Mmr3b_I)0i4*@_C7Gpr{(!9
z2%NinxPeP%N8XucwRrK$`$0*p%dXZWW}mP%jCQ>|g)pcB_XN`>3SUkA+@EmrY55B|
zO1eu9iO@TeXFGn&Z_wBNYK@(BhFMu``O|Wva~e#sxAZbyjM`vtZ|-;eJFbvOvBFH<
ze0gPpm>{V1f`SA^A1g9cZ-k6!Y;^hYD;$_SN&RN26k=Weg)>{AF2R4wLBB?LL8BKpO%YgDNB7y`&&WpOsN{qxs
zZnl38EcEULBS3ZJHS$>!KC)p^yF06edl%T5NH-Jh(r9dAqVW<2=jnL>&nXQ8c`+(W
z2P*`0=f`pybqNzqn4Oz@^7ba|tiVHud@HLJ0bwu^V37Uee_vj46!r(k1MWXEa*Uoo
zCH2jKVS@Yy?b*<9ifEqc0s(LMo_aV^qC8&C=j#$oP}<+O{FVVnZuwcRu9oK`j3ZD9J`KFsj9*XfGrXvBv3wJ=|nIJ?w-?tNw`C(8-?UZ*QiHGNNZbL92oTusn21G
zEQHSEIRO-%i1gWp>Q3GKU%S4?qgl5*t!m&VwzlmCqrfVG+!D;Or%!u*as**XAS6vr
zx&XT0jbp2*Aj8X~WJ$^+<=y5iGT`00xX){iE;$uUP9D)=@lc6{8=eHEH{@~pe0^(cM7fF=+zxyx3H{W;
zZ{I}9<9GZD4`jBm_WcUsp7MZ&^i;K3uBxhnjFE4V0g2$-H{s<;Di*Q}0#P|6E)Em#
z(dlsF4oIHgzr`qkw6J0b2k=V&*=2j<(
zRlAVdCa0s@b)_*nJc|HygmDI7NmiDJTfp%FJ4Wy+AOSAcB?vml3lXSUozL39s33Nk>ND
zP%N7SA%74^!E<*K=6lx|tXm)~ptE&}RiGlRpo6imQzKy~-nHRGL{Bne%-7oL#VM2W
z;nC4TV6j_M)6=haLn<49ywJZ0YOkO`L!%d?pg8q4Br9bR4Ib5@DXIpUKCA{SC33w{
zbMx+?t+n-Q0*X{N@#*u%25`H!wl{Q5dpkErwyv#BXC6L;D0CsB1_0154b9BVXk+Uf
zDAw~~i;10wS|0Ay>phb-O-F<72J%Oe)#nAYiOj#{m)YNcZfd5f1#`9WoZ&o>8A84c
z-lAq2j2~d{tF+pv9pUR?0R+M5GvC&&l+3XJ9z(V^Hr>d+mKSn)dFR1ck6jD2>$rDG
zmxX$p525JL5w>}s_?jRNzl6m|P>wDxKClHe8xXHy=B3JL1elqg&?tH4GozyF{i$|<3zJ_e;&`U?dk=uGqPT@AXF0hviCp9Y~s
zzCsrgRD7q?!F##Wgx2<5T;~_yiwo&1S*1!>(lxMwxB56-$=x0txc8Iv$sztKGB`e+n(#6z_dW&
zP~bzgx6{oZPpEdt#D5Lprn-C_rnby|Xm)&iy9sRP6ayE_kdJ(%=O2&%b;~ajPv>na
z;=R_-%R$nNxEju`CvnCgC_Dq~RhC(xs5~z%7*<)nwW$)1(h7_9o}xpMVeq;KUB25?
zC4u9rkY(75gehq}_bevHbMZ>9>q{F?@Z9PgzA1DhEmAv~tsIA4tV`gRTQDt=%BEO|
zu4`Dm)in>WjopkhUBK13w-`nJ`Rn5=kgDM@0BO+LaMeo1jgS;UhkJ3Z4Z4{w`D%YM
z!EkJOeM5tE`EbkMR5h{Ew>MK>9waw+#7Es
zxGT9OW!{2-Ltf2S>2gnXY|icoVzJW7!QuJL?X(i1=EhkKFp^h%atPpq@v&&)kc3%q
zhS5laR=eJy87K^{WRs`&UFCB}1Oma^L*P&r8SCpITLJ>B5U`8HfBg4vdwET4atDIn
z3?j4=s1(a3(Ih+%!l7p36Q0KokH41UzDYcrl6Q8p~EqU1&Q2
zw*qH2689X;WxZ$msn4}cKxwWOy&CQ9MS=Uah~Y}}!r@E+h@cEH3oZ@dtXbJ02Hb_F
zrf*2FW?=_KDj!VPO{Q$wFa`6OS5H&<2G}Kl+XsKd+kt~Wm{(M@7$}lvgax7xR1gu3
zs9D<=fgE`5%yqs2<$Qj`lWT0wettO_8M?xWnHw7$hW!1@>zl{nU0UvbVp{QGN8ro?
z3kQA%8wUh%N8&*d1GFPqKkmY6y!32opV&oszzUI-Zv_jH}4Ge%>#GA6uSjvM}6mSTW1161kYIt8ER=s{i?=}
zKu%soYH9ggTjK~YP3IgrzVd5q&ut1!lgi{0^~{lJ1}=I)|GfghNX-h77~rhgF)5kz
zM)K+^OB9=3(in3={d?sZ;mSPJJ5V^@V)x<1qj}KLlDgKGCrP@DJ8OLw?acr2I+&gE+K}m1@b3^`^d*T0gIa=&krg0d2~j|PJ0Cm
zRam&Luu=Y6|0c>Jq7;6hpfB?f4(
zn}o*I8~Ne!w&x4}C|}SshEI6d_^Pk5ErXgVvveB-h654io>``X(}`?tJ+
zK-GQ5aJfZMFqJho{)P_%M_g^aKD-yex{SkXDMKiD1*k#Bg9xSpr3ig+CAY-Nj!6!s
z-0@kq#I9y~T7sBva6*lQ<^uX5sUL}7@ezW!l`J2I3OB?QpsEKXbVfYUn}o#ETa@06
zO%I+21L47|@NyM>^|5DmicqsHgHj`@2dQ0VVFsZ9K1`k0{dkG!>zx_0)6|`zyaI(o
z`0-nfLjVItxnSw8t}22%Kqta-;`vy5q5uMSYT46kW1PB^qYAZ#4sah^-i&5OOK+
zfEM%N50I)4lYPCt!EwaHm|eD@@Q6N0LdN%prKlR8;MA6{_I^z(_bYh^+MovJpNqb!
zC2GuaaAtpqn8E0rU4~6nZy>g66v~q)?)ds%Zjd*Z(kWIkbSRy;j1`J;s=G4ph<@!<
zK%Z8p_`?Uaw;mtLTJ?JpmS3ezXtd-wF?agG5%=gG+vI+5E3I#%}fy?)15
z=#C#GJEK@Fv1`+Q>3G0h)e$7PnHT3Bd7KDw64B=^8DnHmqx68tU0OJaN28*jyUU?Y
zW*PcK>cdkYO)e`aDFI*14=7x#>*x?&hO$?(OO6WT@|9LQ{-k1e17tK&`w5SzI1y5=
zJj!v>dqB=yo~)AiG!}s;{^%OO07KX^DCSKACJ1Si2&oC`R1;32pQi;=Pr*mW++G)dP~C(|Xq@m33k$y{FF45V_3C{3BfhDReghfZd27%^d89=y6V
zKR*6Y7@sXb&+V%j`M-WK1H6JUF?5tOni!!h-nDruwM0lim1F8a-!ZaLon)LESp|3j
zAL$|%o=l9rScgQjLk|JubuhDEI@EBOyLweiRa0dKf;t%?w@S(gFzZC7^oaf~K?HZb
zw@#jXC6y(?rSDjRQ5~8Xl`qPMWW@qk(F^`KfV`Z;FyeZ72nt3>eD>)i{EKN1;tQ>Y
z8A~a!vqC<)NODTNl^|Z?*#nz0vj6E~(t#2yNK@ZomR=K#payhl0Z(Krh3WG=J*#EX
z>43KZ%_dg*!OJkyWmxtUDRz^U2>t+S;1A();P1DRM{c}0)xU%hAKTR+iE-jjNV5e?
zT|(+XF_>Pp7NteW9$|q7h{vd-ToS!#Ua5;u7EYeUAy48L0!0D|D7@*JIa7RmKfwSb
z-7r$eRB{<=yORIh4O+(1i>(s|f3i@%N$G$j8&gq-Onjs=P5t^%+*6i>+{GkV>mo5Abl_e}go(T;0ec)Jd@+I~8D{i$s>rJOO
zmK;eEk^nywBdIUGyw^o`H-}QZm_!og<`W+D`a{uf0*W5PI@q(GU7Mh#JOZT5
z7J$x#E76hI2cm$OKw*<8&k?~5XK)7a=a`izyU3w@Q89#}dLqbG@m}|Yr?DNPw7Ly=
z`qopKrI&GRBsK|noMI9_9dBLobok{-;SDx;ZhX1Q5~jBWk|l}{p`&xw1xns)fg)4K
z;Ee@!l}n9vEMB8iVaG|4FulrHU2Kj|_#)S%vf>wV65{Z^9F74Umb1OGhN+S2W4?78
z-u5vaP!aR=d5y$Lk}Z&YfNK1Q#=K+5>1HcxL_)gqpE0r^7GJtp>lIQkRsm2qa>y*s
zhgO`(>!2K3kP^en*lXC5e5ylxQx77>R|ng=UYzAcxZs|f0*PYfedA%0Lc9~yLl;J_
zVZGY@Jn}A2ZgLO8Uw}d9OJP@tbk}B`#K|WuRs3!
zuuX^jPM?*h=z|Y_O+SFDQXXhps7N6eO(8u2j#XAwE$oXtS|TOdf&-*CHI*qNkdR;U
z;R7>ZI+>i1Zg9Ya?1)~b>x-0`8I>%hny)YZ*O)~&0M4K9dv*=m^{eMW?5`iF{AX^L~aPNzw&-0e#qUoZWf?UZ4H?mjO7o`mzlvTiMf);GZ
z{L@$nb#U5Pu~U$TWE}D2dou-0)$}fPZt${(t*k!V0mD`3@PTLcCW~
zp%F-;5BI`7S9yJ06_4S}z!$D9wJDY==<{v?px6Nq(19kgY@d+6WA-KKu?zHkPELng
z({GaSR0nFj&^zS_c^fPvcfn{eD7p?96f^zVhuKg&7K%|d9#U}uN9G8k#BSRAa-QsJ
zTXizuK%B}!`r8j6(jMC>rU5O@@h>pR>HwiF2`yHzgOM>9lXTRWFH41I%d>v|ZS|NA
zj0qrM$RlWWapDE)Gvv{HJ}A{vi5rI(Y;xgq=11u0Q
z?mKq)_kZ6OSoG@mHEH|1yANvSE85F9@g;82&vlrsF*9~HuamxrvOC^c!Z+ABBknI&
z7Gvrj8*>`QzWFF?pjGUdE}!g1r%-HtY*lL9d1eOXlkrl}
z@^;Il460_9oeq-*akOOjD)xuT%Ck)n1i9>N4`byAhH!sbc9itPjGwK4DC)@TTtq$B
z8!i(cN6B`-Rx_;=Io&vWELC#lC8)#y-RMZkMbv6>h7n-4P|Pc)--b>0M0q2D7n
z->IoUTejbdM<xC-B_65`Sj1O9tc
z3T!OMYh2JBVkVBXji0{lGrY2`h_~?wzTn7~R}?su%M3HP>dIWDCY>>rJ2G;Rkk7^%-~X^Mr%YKv?->Ga
z1wUCDD6P26M+0tuIOjwEleQXYyr^P&dCiUN>_9`bzT&XziP(y+xVsSab}
z9P;ZNR0z$0DE#>0w}e4(wN!&m%`^eDC-{Q1d{F?w{&IGhC>t~(lQ<3tlFg8IxT2-Q
zS!Y*3q~LA(U?SP;Ys_RlRG{84@w!Q2YHAc{aiD|f^%}3#lCsro!wHKUoo#Vz2VksV
zw;v(bXG;~B6jd4&SL#OULvYm_6h9@kEUN7D-)R|?y)KubD)j63wNqkXr&oG4$4uqA
zL){<9y?Dj!I%G}-8;_)uRcg=_1hu>&8+-ew7IJ9gms8M_R}Wo)Y2%yRYC^?k2ntqk
zru1GPIo}85{Ws;)!hvADrd^X?CD_L(f8?gA7rBdzzZn}tpSdpW5zySXLj|wA{H!ZP
zIZSz7`>dEpXecx{3PJ1NQlMtnar9~%SCm$v{*{UJw>KqGJP3p0hmLbJ`nd0t_amdAe#x&7=Fr8p_<{h%!CB*a3HdIn~%BAq|lpjCnZBc|2Np>nVuO1#!;ZXA#
z6pVtnQ62=2&30Q*XZ#mDOui^5o&*~_(*@V@S@)al{9nw~gkfxjOFbxtG?i24x;jV@
z?QpY~rUpYGQXvlOVGRV89Nu;vzgd#M$@*id|76?jdJ48I-OAP$QJju;fkw-TPwrf?
zY^P4CNfm!Qo(#W3JNO;`2cpsS0a^BXS^Cgtf7YPmX$x(1^R-SU9{S*nB*^tG-iz`(
zLD;m#z;ICAQJtM!HXbF3Q@JLkN%L=%kyR)^x+GrK@
zTWDLNr0cu7h9)cWpu6H_?9t|YgTp}PB5n*SnjTZFO%a^3gPv2U;HGAUqkSzMMxJvV5uT^CVP1sCO53BNlf$pd1=E21o18r2v?#1b;r`$5n
z`ns|s#60fQkQ0;~rbbp3p)IHu$V)@(pAYWe*QnQtq+fU6{{T#5akTc;Xzd%AWb(}4
zw~mZN{u{*na*7CRqr*bMeq0P&8u@)N0<3Dw(h0sQwY10SsjaPT$!~A1e+n@=iNJ-1
zW)6s)kD;D(?k9*JJ$fD-wG%c~O(qlR&!9k9HB}wD7?p7Q_7|Rkxa7q)u16aFN&gGO
z;>HrNebp{ph%htAW~fptFnLr7_1mv)uNK2b@<2a9sOBIcmEs=V5ueuawXN@(^+q(HTB~j1S
zKhht!;bRe7_rKgcdknC_3+Gim3N@@IPvv#>G3Zf3m!zZ5pMS=PV}iN^8mXK~o`DuZ
z;`RRS=Ch95uEKEI%0A!8Ko&LwG(6TpsEm&@rNOL0uUhHM?Ndz+6XSx4`57Tbr^xk~
z`~Fc-Zd-NLexz5Jj2MVh6>f+B_&EY^HL7G72u=Id$w$R{E4`e8>I4r9%sJrXw~mVp
zivj@94)*rxKCQ0_j~iX@x9d;M&2hHoD;Pm)%&LS9WyV3lJ~(`n>s`lWGn9#jL0>{&
zFn--XtG_=GtTrpFY}lOIxg~R8&AF&t74SEpYy07sbw77i|F6Ho@&XGVt$n|J
zrx^fyZMzyGyE+eA4sOr(*7NJ9CYQ+KkpHL}L$^1WDQx1PjCZvQB;#npivo};5)ynN
zRMO2*g3nSe*PL-QlI;hhIPGbp>zx`pjp)Dkp?R=2u;LEW=34qm{;jrag9&Tj=XhAe
zAW992-$-Iik|5^k(^yq?OyvF-;CTd5@i(JWWz!Wf7j#p+C)O4U^wE8YzQx#CAx^#C
zD)wek=tT_w{{3wEWWA*UyC{m!#se&&!Q8wG3g)bo3mVDGg1`f+X^GV^_OvYKIl~m4
zL0>Z%`f@ul@o-U{fBUnO8TDu}7(XzK0?D%4J7^ks_J32cNqoipJ3(OPJltf3zQhlo
z{)N}(($?I(R%Lm&(;-c(M_1>aH0l&2!=7&Zn|k?9u!oKQ+VHx}+#8;gBWxhsgWNwT
zbo$PY{o?~~eCdnQ)SL&sYKK2;TyZo1%#6)FSQ`(6evo|
z0V*4Jc_IPskzALFdeE!od%@>yo|E#`GK=SCvXr(Yc;Nx7RLR?(YJ)ab*?a>-%CJOl
zsXI}?hae=d1>Pd9m{kgYLEhMJp>
zv!}(iqP^d&e|ZVR?PZ+ygJ{F0Lccih5UVQ79)b_DX8+uoy4J>5OriV{u*&!E+mqn;
za9w}BycB>Ov~tmbug~q$q6?IL#;_W+F#`;?H)w=Ap=SLIOb4Qwz
z>+0)cU961^Py?`P^?;4&`Q@6HxTUGC=&$AfYwQDi8hqk3iwbO+C7D=Uw)$hovp`ao
zGz4i9k}Ht33QI$XSt%&zev*k7I++m<@{xGvyYLy)x%a-^49o}|4i{Z%>G4QXKZhT&
z_$J3C-He#1R|qXPFQ<^w5mUK(&-%UpQFgVCKjmf#J*?1ZYEz{lhR5Lq5Iy%kFx*SZ
zlkwVAQg*;rS-zy6BObT}=SlFXcGEZ)mvEqZ_IeWB6lWwCv_JX}*;reTS5wjY1t#1d
zxsl{Gd#K2g@_wFZe%#Xes{3AsnE}{gL$_3Iz;Ts?@~W9)7IMO-p{olzbddwLr~$k7
zrnsrxI)mcZb9VOGkNF;aPHyKx8Ep=A0$S*GXqvUkuY&1EOBg*iyW;p
zS1%%?|9oGVvey>mmmta})Zl4YQ&lA@ZZr-c13!acXlPJNBs5%D6X0*&RrfwX0rwaH
z&pJ`h5IR^=!LRZ3)E)fCAKC^Lh?KIoHz&YF(J=+G%=&pT&?xGp0Hpxy&cW4(ZYEA*-v*;GtQ(Ro^w
zI%I16+!uE*ZGziXe20nb3Fu#TRugWI#0^Tuv60D!>118f%Vf@O+0_)&-4ObwJXOL8IC$2~>j&*_@J$vAnG7t}*$G3LQqBJ|82SI;(}B-%mMz5A9wdU-v@|
z2;<9N6DpN%bd`r(5T(KpA!A7?7@I?0CJf`$zNJ^w>n>Ngba+vMQH9I=dNpswrgr}BG+O3u(<0*#Ou&hzILK)}3d
z^6aEfsN>xDaRO_6^E5*t>0X+hBAicpnEdwU7Zu?^6de2zhLVE(*mmpPPjaUGcy&7f
zvQOh!^)YF(-!YB@S$$~XK&V~T0|uPPYEbt2wln9Rm#mh!xlf0IeEnKLX0jNT94
zHWzFHu4-!XN??~=7o59b6{b9)h1|H&_A+VhyOtg_r28G?f~pOq`l<<4mr6TD<@2_E
zEmca}r@weipKd(_hdWOu#mU6C;_qJ}GgVZ|+sCILyCLUh#vmKyww#v|o!Dn-)o3
zX<@1V`g1!)ymdT9N}t#3=IH=a1B?k2GtfwI3!Pi5wH4i-sKGXZ%n-@G)e-h~kPn!r
z!IPRBA9=Z~b4!Giy_#!SBc6B%|J1zGm-IBd{VygsuuMowk%>PWEDm+neMbDVl!3!d
zo&+SEK8%K4mOx3T*P<7kW={{8rbQK00Kv*Lq_-EA03h^4+_4uxB8Sb!Gc;hUOz6gCM+s
z$A3B`I2!9YYc%}LpYJ0#=#TNFv^1dT)775JC5^7CTh=zYcql?57BM$Z&jw*oL$F^U
zle(7zOM5rj>0sCbw44L*#OvKG6|@SRM|unOzU(keQsAfJlfpb)kkCepE+m-sn*OtM
z5GD$e62Lot$#Cv~t!%&j4-GgPek6nBPE_E6=R9scG0ysq-lXBk--CAU|ERNgI@K
zLm;H|WltE$0>;mtW59baqPR%r&T*90so)6-<(sC&N{x(0!bMh9ny}Ay)pZ9|D
zCdLSw%>p_o^q#XyNW=FC1$xhPb4!rB(#GZ=ZmPE4buSQ&9hA$6@1Pu8gLXSq2^{MC
z=ATv>6=iK-fkn?xna`c*?+g^!J55rc17E@);F|(0FVh%XLj&SGdsK)Ap(kIZ1~daU
z_3+JQ+}zQz?Uvv``=%zF=VelK9eDY;2DE3Qq+p-=dzx?JVe0@`%Iu>z{+aD=pg&{Z
zo;X`C-{0!%Hn`$L1ZGdA9t9eXgU@nKk@GJ+I7qHn6#{COAUHiU@0ARxw%~;R@RVgl
z){U-S$AuIZ>r71mIJZ%G*iwD`y2@|^Xi!4I#Qu>w{G{0*_8Z|#^S`(rD|?X%K6WkM
z2NAe8yUbJ5HEAWXG5R{$Ib~n>D372@C3zAsy4e;QJ6*u~h1EC%`e*$c1RnXzmzP(}
zjV)X4mcI@t4Zbltj95fNxf=o>Fv~~>6R-gw+jq}ac<&hfX^r7Zj&r6^KlJpBs_b!m
z4GMOC0OxBT0~)60x}|`rLCO&pv6>E_0&-RjxEnXC&aQ(R(i6#2tlAzvInDMkS-zMb
z-s&p^3Bf+A4>k|D4!~9`p|Ci-B2KdZ&h*!+$h)~BC5FwumS;c>FY(kjOgL4}u9Hb5
zF8HdLI7(`!`K9Vr=*a=W1e|a1^KQ()`!#TuXcGD%z&Hil^Jyb#I~ZshJ;Ix>m8D~R
zU9Ewrd$YWpy6tru@~*Rj!pNyp=6x+5Hx@)@=8D$B+`^8(Zc(6vJa}{N&F6`YHlFFc
zo%QuH`|TgawOwE
z`LhxsH`hN}S%G^3>b`mN_X~?*=qJh@u?IXg@-Qx)NHZzD+-m0t+R>nx=wb~erBpa}
zd$aKy5{SM6i0+@k1yNCfw`Z4L+^mB58o#~4AvAd_s=@6#4}#eKEpLuBZ-1AcHWogB
z-nb&$|Ngz4zE2_$^V@Ev{fB|=#zCARys
z-;3XO+;-GF6f8{foM{?~I^@x@HLRwA3hE6nC=hTj-}(Ic=@-fi5INw5tggA;JiU9f
z83?j5=u!}Y@G@pH{2(gmYJ;-OgDAC-YJ)Dt<70roJA+I53vm0-fW{d$
z`$Fmi(VFltI>55Td(Nu=_~&fkN`^-e=HEyd5>)oRfB&=w-PrhtH;5-BY(pw}_u&Ix
zb?dL(W}5o(vF+lwH=m_HwUUP#u#CVqKgWUFvsyYl2(E}J;VLykK9oGcFZRYbscwO}
z`;EO>j0x1!*vQD0P6u$~?pcAo8WN%%0PPFUEad*VEMmpb2>*z4|QdMEW1g4PCovyB)y`mJ4THq~gO`^OSyHwW8xYWfWAR~XnZZ(v6?
zdE)1?ZZHe0Gvp23;q07@3di=`dm_9ZcZ!pxij0YOjd)ez%~^BdA1hK`PIIB^2T
z{xt*rC&{JP1{-S8hN;g%8i1KA{C%(M(Pqp!ecnYL>&)Wq@2Ky=m%!Kr7r|~6mYFqD
z_9@+ks_Xoq<)PpVXCmQ#aLi_|Svu^nNb<;Xu<+gu23VC?NVbQ-WcHYDdTZkgTCl3>
zAS6HEwNZ4UyrJnI1^s3u{7;CYz-7WAf#aL<^XVe=Q~$x3oG|7qD6x5I@-}x`w)mRC
zOS4R?%<(2qeMPr4@`^X=D8!LH>ugiXGcZvgPJ2O
z?~FzTXcgU;(Hl9j;8aCWTI@R80LqCwLCg+8pLo9q7rIM}4{E~QP%*YV4ic!Fs{YU;
z0dQ?5zd9q`q1U3Zh=hO10m!jFfRSProUFz|Uk8bKAM2RFe$8mAG>nTBaxyF74*|(a
za0Z=Lb4HX+3l#7K$O>3fprHVykmxpp*8=~1mD&q{W{$$*dXm6^cHKDVImw
z`aF@9HFy4bJJ^?P0=&1_klOZPgYAs9Rrcf~bsyL}XsIRhi;vh%jpl0@vd|*2F0xQ@
zSOL@ZT~qN8Sm|_v1oP~k>tqDQKLBFyuS@6po=7{tYpPPR!;n9JPPNMH&5kwfu0dal
z@B7M5WR(&JN+$B)C!);4z!_-3s7XSWLz~vC3*GlxpnXm0)lZJuSq0b*fahC#6v5{X
zH6WPzw%MhO2$(K5^$2A|5{359v$eZbmQ&(dnVb7|ZFe(vcA!VF7h{7%f`i)wFLKY}
zVrFdeSUa2#puous9S!E-6n1k|;SEwYa%Qcq8qz7q)-$uSR5(qR^=`&JRg#^wXpkDY
zzAgn#ggJk_aj6W06hQcO%vl|@)MnOMmiWGH>_RhI%0RXsgd?1008}-GgCt=2z!3~X
zKyK*GBf)FIk;N&cu6sFfH~ICuy3gv!&}+C8bOfp(yGr_I=L!@PNs5bT!nFW3ac<#k0!e^`@JL~~
zrU4@ev=kFX9tweqj|Pz_REt<40hK}(h+v5jU}G&PhERnMMnFkD2n63(SM)ElKo9-%5!DkwR1RidI(v~3%m_QF^XJj{#_bO#{x(;v3NUI(WiPhOf|E&$H$
zWnRHTRMVydc&Rn&zP*>q2&%E(6b!12ALcy}D$)`5_AmkOmi~;Q)
zB(9@u`aD>>f@K$K`rxq-jx3yRKM-GTf?it{c^p*aFC1G&r%zmR%hF%u_GEqs0DXC<
zK+qw+p+vmNe?FWr=qyUrKF3L-g{
zYJ5r-&IMcq_)&NbD2E`>OOEjYNBB^Vx|T+av(EU(1bV&A){XjFP)kXXJgxh4)
z{^?f^s3q{6_3p%Ov4YpQIE0yRPTj
zM3_}WIm??KG#Nd?7vi$(3embCh)&Me&l6%YKwCCGa&y;ao^P3H`23DdqdQxnPW|Wi
zBxqLFamW42eaZ!(BxX|gc>NAC3~&FWFJD%fhR;}GN7!Tq(DgD6E#@$|cbFdkNp_;}wqkUD6Es-^dlwzt+>VhvhFc$NUZ{(OMLDQ@eIMlL`O`yKU(
zC;WgJK)z_{J$bel2y1J8jjhf6+b-MZk*)K;6Ys);Kl|w&2+wkxw9FzGW$nCeuSpfx
zELG>H#l8nh>stwa!(fZyC2=X$ALKhmz)#rK4tYO15Y%%r<1YJSr$cjj`%WMp9W-DF
z-0ii1ECIC{c%(daqnqIZxtM4Sw+ZI-F|h0O?V7V&H@fv?t^iUj#L8!wmC4xXG%OW#
zC5T|)D74QhZq+GZZ&YHbHA&~>JZ?{{dWy+-?jjQ5yBsYWUy8p~msBXWCssl22L~KI
zpoW54K*1aH+V>8VE*G5eyDvGkueUa6&92(a`$>(LMz#r_yFydH{D9xOnDaYU54L{v
zbKRQ2bl8;P^!*^<)TD($*Ywe;;Gw`bS7NhvrvCVt{U$$PqvX
zBLf74CShz2-u>!Z|I=OF6mhA%E?7)1ibXpAQu39a);}j`_38G0r+-breT6Jji`jOYsL}no373ktav%6pX6)`+Z=ANZxO&O%_?_-^
zz@@3ELGoIMJH*cI%zJB3CbRUR{!biK-}rCM2JzG%#d8wrGt!sw;PG?*>f>Q=Sgv!R
z|N7`{=-d;2zhftKHQ)PzB$g;CyEVD&4~TAwdHN2*;u?
zC5;5CoXt*M7$isS!3O&Gc;v7n;5RU0G5&G(16|iX|Bpejvksu7tn)kOblq0OCsv(8
zE(AEd`?Zq|v#pMoZQ_8jLCsoTHwYZKXo>2J^JNriEKi$MH&Pgm!M{WG}tgM(L;*@>@q?3xCK+!h5EgggTy>)Z?Bq)Ua-vMwB59u2G6t
z?F_S^RL*N%K%E$}SyvYu$qrY`(Xv16h^8<(*SD_>tArswS;RFv`F{I!3zz`H5Z4@@
zqBacgy%;uKJg1*B!xmP`(WypTt5IH@uyYLD7a!x7VQM88IVeNmUTEjoq}61x8t!Ek
z*_n$8+c@Ot10Twah;$)EEPb0!O7R@!UI;q|4tgcv(Y2eUzx7Hzg-8{5`sOjp(?e4_Xzf@6swa?w)oUYkI=b7Kb35K90UO*YtWXPNT$tEXrUqlcSC
z1~JECgrt$5hBoQ@Fb>6dBTBxdh+#$u9cs8eB_SAKgVuh>&~~Jf+D*AmS8+-e7h!Ye
zkwJ!|ewsnBX-p;-!M{#=5QPxZCmn`19n+kSKfs&Ra17Km=0iYS(;ih-C_-ici6>Gh
zo;QWsYF{jc;-Xo4QS@>HRmC(%6FPhfM)E}%F%NG>^E(Y~pLJ7>9PmE0JHAgITkTAW
z2#KaJHSN(kU$v1o6Gn#_bx3
z`2%u2(LnX2@%2Kj!H00g-9`MG3XvoQtQIZVV8XbIWy;CJq{#I>B2lnGZhntwwpufO
zC`&_i&a~_HD*I>h*uxcy!~%SkI)x!-shspmp_I}=O)lx8z(q
za{%dqcZJ3W8}v_Uvo7XpTuPapM}Cbq^(?}(sZx1(P_Q9LX|J>ghrO$KA#x*hEQquv
z9PnI}bF4zN#%i}&jF>0X;42ddyUz|HUu{Glq6vCK&B`5w1TF^FKq;o4k?}q&BK+an
zs5!eOE%u7lzLP_lMa|i2urwfW=+N!l*r>p6wcw0I8?eQ%BTO6!5r=h9#H*)`b(a
zk2Gm|L#Q?hAH}+n19&A8NwxGr=lL>cA)
zOURxKf-5}=Q#>C)eI-_R#D(Xk^VPFdbGLeygV)8>H^vVY6Qy^3=8YU8!Ve@9PZtq
zUN5svq`G0dWp4j>qCKn@tfhSJ#puUuna8a*v`i+2gCex!j6AjDJ$h1vE8>>_v`n_=eb$HB3eXhJx7o`zUzu}N@QzsOo!S=k!U4Vqdhu{EuKSvt07@3_oa
z>sI_KgY%2AC5EO@Xl$&wx8ra5{lrMEV7{BY3XvSM3Ygo65d8eY`1`aijTr?Id4=vU
zBvCOZ&~E9I-+|iYrm3o}fzW^6+*>=fzVzvzdeeX(Y!p?f>h+4qD{{)fLguX&$Hb3L5F0LK((L({OqvgV$$lWI-RXKy@
zg%vq=mWT1JhHGkY96iDL7_rIla^$V!pZpLV(^t6C6_$?-L2p>HbQyD=LP6Fi&@r6c
zESdEM&MEF++#4z^x$u?Mn9AU13w>Wk3PwDh@i9D4lp<@A{@YHNf2MBL)vJ6>4VY{)ra^~3ltYU^y@Mqqd
zurkiy+%$e#ni8c7pT`xldqX1W-GEWJH!_r;&Ry3LF^-Mi89v2rCwna30@2K|b#zrg
z(7DQbH2gx?LhxtGbA}vpfb$^ohz&=4$9L>%8H0@vL=ABM7NDndm)j)lW-QP?SGI@$
z=HKF4Mfy8yI}C7y^3W5yT&MjRp&TK*Xg77sGxL);Lq)cCexx#{IOW`SVCQGKS)rWV
zvN_Sn)#mV>nVRwAoBLJ+WNjnMI2~M~u^iVN)L}41ahtRy6lYRk4j2JA*xU(NP^};sfXV)S9z{@kfXWhy0rNH>h!Be
zd!EMdeY~1%BYitkRqMf!i7N%4CmN-&y=xUOH^4S|ltO2CBfA*F>fJMbbo9p2q>D-p
zyn6lIHg=QRjC}UkUtbp(+IC?b9Y1%SWuY7s6yh)u@(eazoJ)ZmP0RC+ke83cBxvGK
z2{7_~5js2lIX9#)Bxv$XiAdk>Oz0Ay4bG$4pAhA8-{YI%GdfMVSZAsx*yS73fp)5>
zGf{L(HdFSw$cvg5_#y4XNelNc*KHm^=Fi5xA`h*I{QHgP>*n4Fd6qf~F;NrSMa3n0
zrB)iMX<9n3{tTl{8hY#{M=SH4TKgGhKhTyL?vpW#bJjAc92d$m6DX3n(7h1$TabP;
z+Sy-kG`y_hLvO5o8BBGCy?2;q)VYdG(~8W!X~a9miZLB_siaAzNrl3}v4qp&Y8is?
zrKq}-P4ArLZ=23+aU>KE7Y%>HV4SNi#dV;w%sQ>p`Isvnj48yCU_PA%wt%Rc$t{X;
z)%e3fcT>^GTw;;f2ewV+_@UB848|^!6z8mUQY-84^ZOhVTGlzQHR|0n&%aV@Q9IG)
z>j}f95)D0VE81rm`x&7#3S;<&o#6{Mrzp~-vLk02->0j_m3vJ9u&7C~+nv;_6fy9b
zMvNsEMJ{}YxXSKJ)WttFEg5-Wr=FRXmONI|mwZi@hN9ilt_;RmAe))Vu?5|SWDYzT
zmT})>f}O9dBo&htDb+p_OoZb~8JOlZ_IrW{w^4R<-ZhP)4
zzC1c23$=(0B`sMCIN+u8%rs7Caq+LX4m_rnpVES5CX>`GDl!X)Klxp~+S}5iSz>iz
zUmC`=n;Q~*AUC{Y{04GE!W0vS8Txqj$*3(Y&!U<2cE|w99cX$|@D{1KQqA-)j!Zc!|a0M$7bj-jXGYu<7?m
zQXU@r{eJ#PQ55qXTKX@T-B;Ve#<%%>-{xPRlcIpP|847n}
z{4L2wT;WM8yvlsf2zUPk5C;{5Ww!cy&ekX565~lyJMS8|k5AfVG&XVq&VQKiv#qSI
zKB<#KF`-M)5OpmQI&N&2^b?KmokD-}6=7>?%P2MiQ|r1(@_hfU^9u3ojcU_ul5&D-|Z};__
zR)C!T^i6pwP=qR!u9VCy>T%U})>1=voh0BC8oJyM>5zB#IB(~YOM(I)^2bk9qkU3H
zsOsh>b;pj&5(2tbR&njKzWw{)X<&FtVBnQ=#fKH+5^NkCwuj#tmhoI9=c7GGX~hX6
zqkwZ|N0hS6GMARlRCsmR1m_J*Pgg*VZH;x-xeY*qO`oJ1d7ODP
z^l02O%c^)UK?0`yp8U>63TJC9#^PUw>3AE|w%cd64TUl}bt_2FG>e3PtZt
zOq6*xas22#z2VETX=#-eSW_CugcY3s($;$^8?IJU^7uRvJ647~QpX#=xyiMP7JR+<
zZG5V1x?X)^B4?~-279`Y|A_bdCC#|)|R!sVby%WkgeSCuQ+c5UM+epvzpJA<(*si{uTK7Y5qqKd{wh+j>im;F_
zYxse3>-=e1?DCQcD+PN(!f<}6b~}kmN`zc|{`T#O#hBWu_Zg~jLh)=9mWdu?`D*=S
z+oR`Pc{?*z