From 2ba6d8fbf2fb6face91278dc7a21de037b67b96f Mon Sep 17 00:00:00 2001 From: EfeDurmaz16 <75971010+EfeDurmaz16@users.noreply.github.com> Date: Tue, 23 Jun 2026 13:03:49 +0300 Subject: [PATCH] feat(kotlin): mpp/session client Implements the client-side MPP payment-channel session intent for the Kotlin SDK, mirroring the Go reference and Rust spine: - 48-byte Ed25519 voucher preimage, channel/event-authority PDA derivation - open instruction with payer-partial-signed transaction - ActiveSession with monotonic watermark accounting and overflow guards - SessionConsumer with retry-safe commit/reconcile (lost-response clamp) - Full session wire types with SessionActionCodec (internally-tagged union) - Cross-SDK conformance runner validating byte-identical voucher vectors - AndroidDemo consuming the session endpoint end-to-end Reviewed by Greptile; both flagged concerns resolved: - SaltStringSerializer reads raw content via toULongOrNull (full u64 range) - openPullAction channelId-as-tokenAccount documented, matching Go/Rust --- .github/workflows/ci.yml | 2 - .github/workflows/kotlin.yml | 8 + harness/kotlin-conformance/.gitignore | 2 + harness/kotlin-conformance/build.gradle.kts | 23 + .../kotlin-conformance/settings.gradle.kts | 16 + .../com/solana/paykit/conformance/Main.kt | 90 ++ harness/runners/kotlin.json | 6 + kotlin/README.md | 14 +- kotlin/examples/AndroidDemo/README.md | 26 +- .../examples/AndroidDemo/app/build.gradle.kts | 4 + .../com/solana/paykit/demo/MainActivity.kt | 1142 +++++++++++++---- .../java/com/solana/paykit/demo/OpenApi.kt | 250 ++++ .../com/solana/paykit/demo/SessionStream.kt | 199 +++ .../docs/android-demo-screenshot.png | Bin 37502 -> 254664 bytes .../AndroidDemo/docs/e2e-1-launch.png | Bin 29005 -> 0 bytes .../AndroidDemo/docs/e2e-2-authorized.png | Bin 33976 -> 0 bytes .../AndroidDemo/docs/e2e-3-success.png | Bin 41961 -> 0 bytes .../AndroidDemo/docs/e2e-signature.txt | 1 - .../solana/paykit/paycore/PaymentChannels.kt | 216 ++++ .../protocols/mpp/client/SessionClient.kt | 370 ++++++ .../protocols/mpp/client/SessionConsumer.kt | 83 ++ .../protocols/mpp/core/SessionActionCodec.kt | 59 + .../paykit/protocols/mpp/core/SessionTypes.kt | 230 ++++ .../paykit/paycore/SessionVoucherTest.kt | 70 + .../protocols/mpp/client/ActiveSessionTest.kt | 132 ++ .../mpp/client/SessionConsumerTest.kt | 153 +++ .../protocols/mpp/client/SessionOpenerTest.kt | 92 ++ .../protocols/mpp/core/SessionWireTest.kt | 78 ++ rust/crates/mpp/tests/charge_integration.rs | 9 +- .../client-charge-integration.test.ts | 66 +- 30 files changed, 3070 insertions(+), 271 deletions(-) create mode 100644 harness/kotlin-conformance/.gitignore create mode 100644 harness/kotlin-conformance/build.gradle.kts create mode 100644 harness/kotlin-conformance/settings.gradle.kts create mode 100644 harness/kotlin-conformance/src/main/kotlin/com/solana/paykit/conformance/Main.kt create mode 100644 harness/runners/kotlin.json create mode 100644 kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/OpenApi.kt create mode 100644 kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/SessionStream.kt delete mode 100644 kotlin/examples/AndroidDemo/docs/e2e-1-launch.png delete mode 100644 kotlin/examples/AndroidDemo/docs/e2e-2-authorized.png delete mode 100644 kotlin/examples/AndroidDemo/docs/e2e-3-success.png delete mode 100644 kotlin/examples/AndroidDemo/docs/e2e-signature.txt create mode 100644 kotlin/src/main/kotlin/com/solana/paykit/paycore/PaymentChannels.kt create mode 100644 kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionClient.kt create mode 100644 kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumer.kt create mode 100644 kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionActionCodec.kt create mode 100644 kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionTypes.kt create mode 100644 kotlin/src/test/kotlin/com/solana/paykit/paycore/SessionVoucherTest.kt create mode 100644 kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/ActiveSessionTest.kt create mode 100644 kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumerTest.kt create mode 100644 kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionOpenerTest.kt create mode 100644 kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/core/SessionWireTest.kt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c63775409..7e80dd208 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,6 @@ jobs: - name: Run tests with coverage run: pnpm vitest run --coverage --config vitest.config.ci.ts env: - SURFPOOL_REPORT: "1" # Reliable RPC datasource for the embedded surfnet (see the Rust job). SURFPOOL_DATASOURCE_RPC_URL: ${{ secrets.SURFPOOL_DATASOURCE_RPC_URL }} @@ -176,7 +175,6 @@ jobs: - name: Run tests with coverage working-directory: rust env: - SURFPOOL_REPORT: "1" # Reliable RPC datasource for the embedded surfnet — without it the # surfpool integration tests clone from the public mainnet-beta RPC, # which rate-limits and crashes surfnet mid-test in CI. diff --git a/.github/workflows/kotlin.yml b/.github/workflows/kotlin.yml index e983a8ef1..7a227dba4 100644 --- a/.github/workflows/kotlin.yml +++ b/.github/workflows/kotlin.yml @@ -69,6 +69,14 @@ jobs: - name: Typecheck harness working-directory: harness run: pnpm typecheck + - name: Build the Kotlin conformance runner + working-directory: harness/kotlin-conformance + run: gradle installDist --no-daemon + - name: Run Kotlin cross-SDK conformance vectors + working-directory: harness + env: + MPP_CONFORMANCE_LANGUAGES: kotlin + run: pnpm exec vitest run test/conformance.test.ts - name: Pre-warm Gradle for the Kotlin harness client working-directory: harness/kotlin-client run: gradle installDist --no-daemon diff --git a/harness/kotlin-conformance/.gitignore b/harness/kotlin-conformance/.gitignore new file mode 100644 index 000000000..67bcc2f72 --- /dev/null +++ b/harness/kotlin-conformance/.gitignore @@ -0,0 +1,2 @@ +.gradle/ +build/ diff --git a/harness/kotlin-conformance/build.gradle.kts b/harness/kotlin-conformance/build.gradle.kts new file mode 100644 index 000000000..2d52ee99e --- /dev/null +++ b/harness/kotlin-conformance/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + kotlin("jvm") version "2.3.21" + kotlin("plugin.serialization") version "2.3.21" + application +} + +dependencies { + // Path-included build, see settings.gradle.kts. + implementation("com.solana.paykit:solana-pay-kit-kotlin") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0") +} + +kotlin { + jvmToolchain(17) +} + +application { + mainClass.set("com.solana.paykit.conformance.MainKt") +} + +tasks.named("run") { + standardInput = System.`in` +} diff --git a/harness/kotlin-conformance/settings.gradle.kts b/harness/kotlin-conformance/settings.gradle.kts new file mode 100644 index 000000000..5c5849441 --- /dev/null +++ b/harness/kotlin-conformance/settings.gradle.kts @@ -0,0 +1,16 @@ +pluginManagement { + repositories { + gradlePluginPortal() + mavenCentral() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + mavenCentral() + } +} + +rootProject.name = "mpp-kotlin-conformance" +includeBuild("../../kotlin") diff --git a/harness/kotlin-conformance/src/main/kotlin/com/solana/paykit/conformance/Main.kt b/harness/kotlin-conformance/src/main/kotlin/com/solana/paykit/conformance/Main.kt new file mode 100644 index 000000000..ce31fd939 --- /dev/null +++ b/harness/kotlin-conformance/src/main/kotlin/com/solana/paykit/conformance/Main.kt @@ -0,0 +1,90 @@ +package com.solana.paykit.conformance + +import com.solana.paykit.paycore.PaymentChannels +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import java.util.Base64 + +/** + * Cross-SDK conformance-vector runner for the Kotlin SDK. + * + * Honors the same stdin/stdout contract as the TypeScript reference runner + * (harness/src/conformance/ts-runner.ts), the Go runner (go/cmd/conformance), + * and the Swift runner (swift Sources/mpp-conformance): read one conformance + * vector as JSON on stdin, drive the real SDK path for the requested + * intent + mode, and emit one RunnerResult line as JSON on stdout. Anything + * else (JVM/BouncyCastle chatter) must go to stderr so the harness parses a + * single clean JSON line. + * + * The Kotlin SDK is CLIENT-only and the harness drives it for the `session` + * intent only (harness/runners/kotlin.json). The single session vector shipped + * today is the canonical-bytes 48-byte voucher preimage; this runner decodes + * input.voucherPreimage and emits the bytes via the real + * PaymentChannels.voucherMessageBytes encoder. Any other mode is reported as an + * unsupported-mode reject the driver skips. + */ + +@Serializable +private data class VoucherPreimage(val channelId: String, val cumulativeAmount: String, val expiresAt: Long) + +@Serializable +private data class VectorInput(val voucherPreimage: VoucherPreimage? = null) + +@Serializable +private data class Vector(val id: String, val intent: String? = null, val mode: String, val input: VectorInput) + +@Serializable +private data class ExactBytes(val bytes: List? = null, val base64Url: String? = null) + +@Serializable +private data class RunnerResult( + val id: String, + val outcome: String, + val exactBytes: ExactBytes? = null, + val error: String? = null, +) + +private val json = Json { + ignoreUnknownKeys = true + encodeDefaults = false + explicitNulls = false +} + +fun main() { + val raw = System.`in`.readBytes().decodeToString() + val result = try { + runVector(json.decodeFromString(Vector.serializer(), raw)) + } catch (error: Throwable) { + System.err.println("kotlin conformance runner error: ${error.message}") + RunnerResult(id = "unknown", outcome = "reject", error = error.message ?: "unknown error") + } + println(json.encodeToString(RunnerResult.serializer(), result)) +} + +private fun runVector(vector: Vector): RunnerResult { + if (vector.mode != "canonical-bytes") { + return RunnerResult( + vector.id, "reject", + error = "unsupported-mode: kotlin conformance runner only implements canonical-bytes session vectors", + ) + } + val preimage = vector.input.voucherPreimage + ?: return RunnerResult( + vector.id, "reject", + error = "kotlin conformance runner only supports the session voucherPreimage canonical-bytes vector", + ) + val cumulative = preimage.cumulativeAmount.toULongOrNull() + ?: return RunnerResult(vector.id, "reject", error = "invalid cumulativeAmount ${preimage.cumulativeAmount}") + + // Drive the real SDK encoder so the byte assertion exercises the same path + // the session voucher signer uses. + val bytes = PaymentChannels.voucherMessageBytes(preimage.channelId, cumulative, preimage.expiresAt) + return RunnerResult( + id = vector.id, + outcome = "accept", + exactBytes = ExactBytes( + bytes = bytes.map { it.toInt() and 0xff }, + base64Url = Base64.getUrlEncoder().withoutPadding().encodeToString(bytes), + ), + ) +} diff --git a/harness/runners/kotlin.json b/harness/runners/kotlin.json new file mode 100644 index 000000000..2229028ef --- /dev/null +++ b/harness/runners/kotlin.json @@ -0,0 +1,6 @@ +{ + "language": "kotlin", + "command": ["sh", "-c", "exec build/install/mpp-kotlin-conformance/bin/mpp-kotlin-conformance"], + "cwd": "harness/kotlin-conformance", + "intents": ["session"] +} diff --git a/kotlin/README.md b/kotlin/README.md index bf7828daa..367ab02ac 100644 --- a/kotlin/README.md +++ b/kotlin/README.md @@ -110,9 +110,15 @@ curl -i https://402.surfnet.dev/paid MPP_CLIENT_SECRET_KEY_HEX= ChargeClient https://402.surfnet.dev/paid ``` -`examples/AndroidDemo` is a full Seeker / Android demo app that gates one -endpoint behind a wallet signature; its README walks through running it on a -device or emulator. +`examples/AndroidDemo` is a Jetpack Compose app that mirrors the iOS demo: on +launch it fetches the playground's `/openapi.json`, renders the priced +endpoints as a tappable collection, generates a local signer, tops it up over +Surfpool cheatcodes, and consumes one over MPP. Its README walks through +running it on an emulator. + +
+ AndroidDemo app +
## x402 @@ -135,7 +141,7 @@ The Machine Payments Protocol charge intent. The client parses the |---|:---:| | `mpp/charge/pull` | ✅ | | `mpp/charge/push` | ✅ | -| `mpp/session` | — | +| `mpp/session` | ✅ | | `mpp/subscription` | — | ## Vocabulary diff --git a/kotlin/examples/AndroidDemo/README.md b/kotlin/examples/AndroidDemo/README.md index a6f7fe711..082dd9409 100644 --- a/kotlin/examples/AndroidDemo/README.md +++ b/kotlin/examples/AndroidDemo/README.md @@ -1,10 +1,12 @@ -# MPP Charge Demo (Android) +# PayKit Demo (Android) -A minimal Jetpack Compose Android app that pays a 402-protected route -using the Kotlin MPP SDK at `kotlin/` and signs the transaction with a -real Solana wallet via Mobile Wallet Adapter. - -Tracked under issue #114. +A Jetpack Compose app that mirrors the iOS PayKitDemo. On launch it +fetches the pay-kit playground's `/openapi.json` (over `10.0.2.2:3000`, +the emulator's host loopback), renders every priced operation (read from +each route's `x-payment-info` offers) as a tappable collection, generates +a local signer, tops it up over Surfpool cheatcodes, and consumes any +endpoint over MPP, surfacing each charge's settlement signature in an +append-only log. ## Layout @@ -14,7 +16,7 @@ kotlin/examples/AndroidDemo │ ├── build.gradle.kts AGP + Compose configuration │ └── src/main/ │ ├── AndroidManifest.xml single launcher activity -│ └── java/com/solana/mpp/demo/MainActivity.kt +│ └── java/com/solana/paykit/demo/ MainActivity.kt + OpenApi.kt ├── build.gradle.kts root project, declares plugins ├── settings.gradle.kts single `:app` module └── gradle/wrapper/ pinned Gradle 8.10.2 @@ -81,11 +83,13 @@ destinations remain HTTPS-only. ## End-to-end screenshot -End-to-end run in the Android 34 (arm64) emulator against local -Surfpool + the iOSDemo's `MerchantServer/serve.py`. App shows -"HTTP 200", the fortune body, and the on-chain settlement signature. +End-to-end run in the Android 34 (arm64) emulator against the pay-kit +playground (`10.0.2.2:3000`) + the hosted Surfpool sandbox. The +endpoints are rendered from the playground's OpenAPI spec; the log shows +a `Stock quote — 200 OK` consumed over MPP with its on-chain settlement +signature. -![Android emulator screenshot showing HTTP 200 and settlement signature](docs/android-demo-screenshot.png) +![Android emulator screenshot: OpenAPI endpoints and a settled MPP charge](docs/android-demo-screenshot.png) ## Expected UI state diff --git a/kotlin/examples/AndroidDemo/app/build.gradle.kts b/kotlin/examples/AndroidDemo/app/build.gradle.kts index 73c641853..14793864d 100644 --- a/kotlin/examples/AndroidDemo/app/build.gradle.kts +++ b/kotlin/examples/AndroidDemo/app/build.gradle.kts @@ -80,6 +80,10 @@ dependencies { implementation(composeBom) implementation("androidx.compose.ui:ui") implementation("androidx.compose.material3:material3") + // Extended Material icon set (CreditCard, ShowChart, Verified, Dangerous, + // MonetizationOn, etc.) used by the endpoint cards and log rows to mirror + // the iOS demo's SF Symbols. Version is supplied by the Compose BOM above. + implementation("androidx.compose.material:material-icons-extended") implementation("androidx.compose.ui:ui-tooling-preview") debugImplementation("androidx.compose.ui:ui-tooling") implementation("androidx.activity:activity-compose:1.9.2") diff --git a/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/MainActivity.kt b/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/MainActivity.kt index b0a2065b6..74f88449c 100644 --- a/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/MainActivity.kt +++ b/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/MainActivity.kt @@ -1,327 +1,1029 @@ package com.solana.paykit.demo +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowCircleDown +import androidx.compose.material.icons.filled.Dangerous +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.MonetizationOn +import androidx.compose.material.icons.filled.Verified +import androidx.compose.material.icons.filled.VpnKey +import androidx.compose.material.icons.filled.Warning +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import com.solana.mobilewalletadapter.clientlib.ActivityResultSender -import com.solana.mobilewalletadapter.clientlib.ConnectionIdentity -import com.solana.mobilewalletadapter.clientlib.MobileWalletAdapter -import com.solana.mobilewalletadapter.clientlib.Solana -import com.solana.mobilewalletadapter.clientlib.TransactionResult -import com.solana.mobilewalletadapter.clientlib.successPayload +import androidx.compose.ui.unit.sp +import com.solana.paykit.client.PayKitClient +import com.solana.paykit.paycore.MemorySigner +import com.solana.paykit.paycore.Mints import com.solana.paykit.paycore.MppException +import com.solana.paykit.paycore.Pda +import com.solana.paykit.paycore.Programs import com.solana.paykit.paycore.PublicKey -import com.solana.paykit.protocols.mpp.client.Charge +import com.solana.paykit.paycore.SolanaSigner import com.solana.paykit.protocols.mpp.client.JsonRpcClient -import com.solana.paykit.protocols.mpp.core.CredentialPayload -import com.solana.paykit.protocols.mpp.core.MppHeaders -import com.solana.paykit.protocols.mpp.core.PaymentCredential import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonArray +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive +import kotlinx.serialization.json.put +import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import java.math.BigDecimal +import java.text.SimpleDateFormat import java.util.Base64 as JBase64 +import java.util.Date +import java.util.Locale /** - * MPP charge demo backed by Mobile Wallet Adapter. + * PayKit demo backed by a local in-memory signer, mirroring the iOS SwiftUI + * demo (`swift/Examples/PayKitDemo`). * - * Flow on Pay: - * 1. GET the merchant URL. Expect a 402 Payment Required with a - * WWW-Authenticate: Payment ... challenge. - * 2. Decode the Solana charge challenge. - * 3. Build the unsigned transaction wire bytes via - * Charge.buildUnsignedChargeTransaction with the connected wallet's - * pubkey as fee payer. - * 4. Hand the bytes to the wallet via - * walletAdapter.transact { signTransactions(...) }. - * 5. Base64 the signed bytes, format the Authorization header, replay - * the GET with the credential. + * Flow: + * 1. On launch, fetch `/openapi.json` from the playground and render every + * priced operation (those carrying an `x-payment-info` extension) as a + * tappable card collection. + * 2. "Setup Account" generates an Ed25519 signer and persists its 32 byte + * seed. "Topup" seeds SOL + USDC on the Surfpool sandbox via surfnet + * cheatcodes. + * 3. Tapping an endpoint runs the MPP 402 -> pay -> retry loop through the + * unified [PayKitClient] (charge interceptor) and appends the result to + * the Log. * - * The wallet must be installed on the device. For emulator testing, - * side-load solana-mobile/mock-mwa-wallet so MWA has a target to - * deep-link into. See README for setup. + * The playground (`examples/playground-api`, `pnpm dev`) serves its priced + * routes + `/openapi.json` discovery on :3000 and routes settlement through the + * hosted Surfpool sandbox at `402.surfnet.dev:8899`. The Android emulator + * reaches the host machine's localhost via 10.0.2.2 (allow-listed for cleartext + * in network_security_config.xml), so the playground base is + * `http://10.0.2.2:3000`. + * + * DEMO ONLY: [MemorySigner] holds the private key in app process memory / + * SharedPreferences. Production apps should delegate signing to Mobile Wallet + * Adapter or Seed Vault behind a custom [SolanaSigner]. */ class MainActivity : ComponentActivity() { - private val walletAdapter = MobileWalletAdapter( - connectionIdentity = ConnectionIdentity( - identityUri = Uri.parse("https://402.surfnet.dev"), - iconUri = Uri.parse("icon.png"), - identityName = "MPP Charge Demo", - ), - ).apply { - blockchain = Solana.Devnet - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val sender = ActivityResultSender(this) setContent { MaterialTheme { - Surface(modifier = Modifier.fillMaxSize()) { - DemoScreen(walletAdapter, sender) + Surface(modifier = Modifier.fillMaxSize(), color = IosColors.GroupedBackground) { + DemoScreen() } } } } } +// The playground serves priced routes + /openapi.json on :3000; the emulator +// reaches the host via 10.0.2.2. Settlement rides the hosted Surfpool sandbox. +private const val PLAYGROUND_BASE = "http://10.0.2.2:3000" +private const val RPC_URL = "https://402.surfnet.dev:8899" + @Composable -private fun DemoScreen( - walletAdapter: MobileWalletAdapter, - sender: ActivityResultSender, -) { - // Defaults point at the hosted 402.surfnet.dev demo server. For a local - // server running on the host machine, set the merchant/RPC fields to - // http://10.0.2.2: (the Android emulator's loopback alias, - // allow-listed in network_security_config.xml). - var merchantUrl by remember { mutableStateOf("https://402.surfnet.dev/protected") } - var rpcUrl by remember { mutableStateOf("https://402.surfnet.dev/rpc") } - var status by remember { mutableStateOf(Status.idle()) } - var walletPubkey by remember { mutableStateOf(null) } +private fun DemoScreen() { + val context = LocalContext.current + val store = remember { AccountStore(context) } val scope = rememberCoroutineScope() + var signer by remember { mutableStateOf(null) } + var usdcBalance by remember { mutableStateOf(null) } + var endpoints by remember { mutableStateOf>(emptyList()) } + var endpointsError by remember { mutableStateOf(null) } + // Per-endpoint protocol the user picked to settle over (endpoint id -> method). + var protocolChoice by remember { mutableStateOf>(emptyMap()) } + var busy by remember { mutableStateOf(null) } + val log = remember { mutableStateListOf() } + + fun append(entry: LogEntry) = log.add(0, entry) + + suspend fun refreshBalance() { + val s = signer ?: return + runCatching { usdcBalance(RPC_URL, s.address) } + .onSuccess { usdcBalance = it } + .onFailure { append(LogEntry.system("Balance check failed: ${it.message}", success = false)) } + } + + // Load a persisted signer and the OpenAPI endpoint collection on launch. + LaunchedEffect(Unit) { + runCatching { store.loadSigner() } + .onSuccess { loaded -> + if (loaded != null) { + signer = loaded + refreshBalance() + } + } + .onFailure { append(LogEntry.system("Failed to load signer: ${it.message}", success = false)) } + + endpointsError = null + runCatching { fetchEndpoints() } + .onSuccess { loaded -> + endpoints = loaded + if (loaded.isEmpty()) endpointsError = "No priced endpoints in the OpenAPI spec." + } + .onFailure { endpointsError = "Could not load $PLAYGROUND_BASE/openapi.json: ${it.message}" } + } + Column( modifier = Modifier .fillMaxSize() - .padding(24.dp) - .verticalScroll(rememberScrollState()), - verticalArrangement = Arrangement.spacedBy(16.dp), + .verticalScroll(rememberScrollState()) + .padding(vertical = 24.dp), + verticalArrangement = Arrangement.spacedBy(32.dp), ) { - Text(text = "MPP Charge Demo", style = MaterialTheme.typography.headlineSmall) Text( - text = "Pay a 402-protected route using a real wallet via Mobile Wallet Adapter.", - style = MaterialTheme.typography.bodyMedium, + text = "PayKit Demo", + fontSize = 34.sp, + fontWeight = FontWeight.Bold, + color = IosColors.Label, + modifier = Modifier.padding(start = 16.dp), ) - OutlinedTextField( - value = merchantUrl, - onValueChange = { merchantUrl = it }, - label = { Text("Merchant URL") }, - modifier = Modifier.fillMaxSize(), - ) - OutlinedTextField( - value = rpcUrl, - onValueChange = { rpcUrl = it }, - label = { Text("Solana RPC URL") }, - modifier = Modifier.fillMaxSize(), - ) - - Button( - enabled = !status.inFlight, - onClick = { - status = Status.running("Connecting to wallet ...") - scope.launch { - when (val result = walletAdapter.connect(sender)) { - is TransactionResult.Success -> { - val pk = PublicKey(result.authResult.publicKey) - walletPubkey = pk - status = Status( - inFlight = false, - message = "Connected. Wallet pubkey: ${pk.toBase58()}", - ) - } - is TransactionResult.NoWalletFound -> - status = Status( - false, - "No wallet found on device. Install Phantom, Solflare, or mock-mwa-wallet for emulator testing.", + // Account section. + Section(title = "Account") { + val s = signer + if (s != null) { + LabeledRow(label = "Address") { + Text( + text = shortAddress(s.address), + fontSize = 13.sp, + fontFamily = FontFamily.Monospace, + color = IosColors.SecondaryLabel, + ) + } + val balance = usdcBalance + if (balance != null) { + SectionDivider() + LabeledRow(label = "Balance") { + Row(verticalAlignment = Alignment.CenterVertically) { + Icon( + imageVector = Icons.Filled.MonetizationOn, + contentDescription = null, + tint = IosColors.Green, + modifier = Modifier.size(17.dp), ) - is TransactionResult.Failure -> - status = Status( - false, - "Connect failed: ${result.e.message ?: result.e::class.simpleName}", + Spacer(Modifier.width(6.dp)) + Text( + text = "${formatUsdc(balance)} USDC", + fontSize = 17.sp, + fontFamily = FontFamily.Monospace, + color = IosColors.Label, ) + } } + } else { + SectionDivider() + ActionRow( + title = "Topup 1000 USDC + 100 SOL", + icon = Icons.Filled.ArrowCircleDown, + active = busy == BusyKind.Topup, + enabled = busy == null, + onClick = { + busy = BusyKind.Topup + scope.launch { + runCatching { topup(RPC_URL, s.address) } + .onSuccess { + append(LogEntry.system("Topup ok: 1000 USDC + 100 SOL", success = true)) + refreshBalance() + } + .onFailure { + append(LogEntry.system("Topup failed: ${it.message}", success = false)) + } + busy = null + } + }, + ) } - }, + } else { + ActionRow( + title = "Setup Account", + icon = Icons.Filled.VpnKey, + active = false, + enabled = busy == null, + onClick = { + runCatching { store.setupSigner() } + .onSuccess { created -> + signer = created + usdcBalance = null + append(LogEntry.system("New account: ${created.address}", success = true)) + } + .onFailure { + append(LogEntry.system("Setup failed: ${it.message}", success = false)) + } + }, + ) + } + } + + // Endpoints section. The card carries no internal padding so the + // LazyRow can bleed its 12dp content insets to the card edges. + Section( + title = "Endpoints (${endpoints.size} from OpenAPI)", + contentPadding = PaddingValues(0.dp), ) { - Text(if (walletPubkey == null) "Connect Wallet" else "Reconnect Wallet") + val error = endpointsError + when { + error != null -> Text( + text = error, + fontSize = 13.sp, + color = IosColors.Orange, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 11.dp), + ) + endpoints.isEmpty() -> Row( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 11.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + CircularProgressIndicator(modifier = Modifier.size(16.dp), strokeWidth = 2.dp) + Spacer(Modifier.width(8.dp)) + Text( + text = "Loading $PLAYGROUND_BASE/openapi.json ...", + fontSize = 13.sp, + color = IosColors.SecondaryLabel, + ) + } + else -> LazyRow( + contentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp), + ) { + items(endpoints, key = { it.id }) { endpoint -> + EndpointCard( + endpoint = endpoint, + busy = busy == BusyKind.Pay(endpoint.id), + enabled = busy == null && signer != null, + selected = protocolChoice[endpoint.id] ?: endpoint.selectedProtocol, + onSelectProtocol = { protocolChoice = protocolChoice + (endpoint.id to it) }, + onClick = onClick@{ + val s = signer ?: return@onClick + when (endpoint.intent) { + // One-shot charge: the 402 -> sign -> retry loop, over the + // protocol the user picked (default: the advertised mpp). + "charge" -> { + busy = BusyKind.Pay(endpoint.id) + val proto = protocolChoice[endpoint.id] ?: endpoint.selectedProtocol + scope.launch { + append(consume(s, endpoint, proto)) + refreshBalance() + busy = null + } + } + // Session: open a payment channel, stream metered SSE + // deliveries, sign + commit a voucher, settle. + "session" -> { + busy = BusyKind.Pay(endpoint.id) + scope.launch { + append(consumeSession(s, endpoint)) + refreshBalance() + busy = null + } + } + // Other intents (subscription, x402 upto) use dedicated + // pay-kit APIs the tap demo doesn't drive. + else -> append( + LogEntry.failure( + endpoint, + "${endpoint.label} is an mpp/${endpoint.intent} flow this demo doesn't drive; use the matching pay-kit API.", + ) + ) + } + }, + ) + } + } + } + if (signer == null && endpoints.isNotEmpty()) { + Text( + text = "Tap Setup Account to enable these.", + fontSize = 13.sp, + color = IosColors.SecondaryLabel, + modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 11.dp), + ) + } } - Button( - enabled = !status.inFlight && walletPubkey != null, - onClick = { - val pk = walletPubkey ?: return@Button - status = Status.running("Building credential ...") - scope.launch { - status = runCharge(walletAdapter, sender, pk, merchantUrl, rpcUrl) + // Log section. + Section( + title = "Log", + trailing = { + if (log.isNotEmpty()) { + TextButton( + onClick = { log.clear() }, + contentPadding = PaddingValues(0.dp), + ) { + Text( + text = "Clear", + fontSize = 13.sp, + fontWeight = FontWeight.Normal, + color = IosColors.Blue, + ) + } } }, + contentPadding = PaddingValues(horizontal = 16.dp), ) { - Text(if (status.inFlight) "Paying ..." else "Pay") + if (log.isEmpty()) { + Text( + text = "Tap an endpoint above to send a charge.", + fontSize = 17.sp, + color = IosColors.SecondaryLabel, + modifier = Modifier.padding(vertical = 11.dp), + ) + } else { + log.forEachIndexed { index, entry -> + if (index > 0) SectionDivider() + LogRow(entry) + } + } } + } +} + +// region UI building blocks - Text(text = status.message, style = MaterialTheme.typography.bodyMedium) - status.signature?.let { signature -> +/** An iOS-style inset grouped section: a gray uppercase header + a white + * rounded card (10dp radius, 16dp inset, no shadow). The optional [trailing] + * sits at the header's trailing edge (the Log's "Clear" button). */ +@Composable +private fun Section( + title: String, + trailing: @Composable (() -> Unit)? = null, + contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp), + content: @Composable () -> Unit, +) { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Row( + modifier = Modifier.fillMaxWidth().padding(start = 16.dp, end = 16.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = title.uppercase(Locale.US), + fontSize = 13.sp, + fontWeight = FontWeight.Normal, + color = IosColors.SecondaryLabel, + modifier = Modifier.weight(1f), + ) + trailing?.invoke() + } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + .clip(RoundedCornerShape(10.dp)) + .background(IosColors.Card) + .padding(contentPadding), + ) { + content() + } + } +} + +/** Hairline separator between in-card rows (#C6C6C8). */ +@Composable +private fun SectionDivider() { + Box( + modifier = Modifier + .fillMaxWidth() + .height(1.dp) + .background(IosColors.Separator), + ) +} + +/** A label-left / value-right grouped row with 11dp vertical, 16dp horizontal + * padding handled by the caller's card insets (here only vertical). */ +@Composable +private fun LabeledRow(label: String, value: @Composable () -> Unit) { + Row( + modifier = Modifier.fillMaxWidth().padding(vertical = 11.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = label, + fontSize = 17.sp, + fontWeight = FontWeight.Normal, + color = IosColors.Label, + modifier = Modifier.weight(1f), + ) + value() + } +} + +/** A full-width plain tinted row (icon + text left, spinner right when busy): + * Setup Account / Topup. No filled pill background, ~44dp tall. */ +@Composable +private fun ActionRow( + title: String, + icon: ImageVector, + active: Boolean, + enabled: Boolean, + onClick: () -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .heightIn(min = 44.dp) + .clickableNoRipple(enabled = enabled, onClick = onClick), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = icon, + contentDescription = null, + tint = IosColors.Blue, + modifier = Modifier.size(20.dp), + ) + Spacer(Modifier.width(8.dp)) + Text( + text = title, + fontSize = 17.sp, + fontWeight = FontWeight.Normal, + color = IosColors.Blue, + modifier = Modifier.weight(1f), + ) + if (active) { + CircularProgressIndicator( + modifier = Modifier.size(18.dp), + strokeWidth = 2.dp, + color = IosColors.Blue, + ) + } + } +} + +/** A rounded gradient card per endpoint, mirroring the iOS `EndpointCard`. */ +@Composable +private fun EndpointCard( + endpoint: Endpoint, + busy: Boolean, + enabled: Boolean, + selected: String?, + onClick: () -> Unit, + onSelectProtocol: (String) -> Unit, +) { + // Charge endpoints advertising more than one protocol let the user pick which + // to settle over by tapping a method chip. + val selectable = endpoint.intent == "charge" && endpoint.methods.size > 1 + val gradient = Brush.verticalGradient( + listOf(endpoint.tint, endpoint.tint.darkenBy(0.12f)), + ) + Column( + modifier = Modifier + .width(150.dp) + .height(130.dp) + .clip(RoundedCornerShape(14.dp)) + .background(gradient) + .clickableNoRipple(enabled = enabled, onClick = onClick) + .padding(12.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = endpoint.icon, + contentDescription = null, + tint = Color.White, + modifier = Modifier.size(22.dp), + ) + if (busy) { + CircularProgressIndicator( + modifier = Modifier.size(16.dp), + strokeWidth = 2.dp, + color = Color.White, + ) + } else { + Box( + modifier = Modifier + .clip(RoundedCornerShape(50)) + .background(Color.White.copy(alpha = 0.25f)) + .padding(horizontal = 6.dp, vertical = 2.dp), + ) { + Text( + text = endpoint.method.uppercase(Locale.US), + fontSize = 11.sp, + fontWeight = FontWeight.Bold, + color = Color.White, + ) + } + } + } + Spacer(Modifier.weight(1f)) + Text( + text = endpoint.label, + fontSize = 15.sp, + fontWeight = FontWeight.SemiBold, + color = Color.White, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + Text( + text = endpoint.priceUsd, + fontSize = 12.sp, + fontFamily = FontFamily.Monospace, + color = Color.White.copy(alpha = 0.9f), + ) + Row(horizontalArrangement = Arrangement.spacedBy(3.dp)) { + endpoint.methods.forEachIndexed { index, method -> + if (index > 0) { + Text("·", fontSize = 11.sp, color = Color.White.copy(alpha = 0.45f)) + } + val isSelected = method == selected + Text( + text = method, + fontSize = 11.sp, + fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, + textDecoration = if (isSelected && selectable) TextDecoration.Underline else null, + color = Color.White.copy(alpha = if (isSelected) 1f else 0.55f), + modifier = if (selectable) { + Modifier.clickableNoRipple(enabled = true) { onSelectProtocol(method) } + } else { + Modifier + }, + ) + } + if (endpoint.intent != "charge") { + Text("·", fontSize = 11.sp, color = Color.White.copy(alpha = 0.45f)) + Text(endpoint.intent, fontSize = 11.sp, color = Color.White.copy(alpha = 0.55f)) + } + } + } +} + +@Composable +private fun LogRow(entry: LogEntry) { + val context = LocalContext.current + Column( + modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp), + verticalArrangement = Arrangement.spacedBy(6.dp), + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + Icon( + imageVector = entry.statusIcon, + contentDescription = null, + tint = entry.statusTint, + modifier = Modifier.size(17.dp), + ) + Text( + text = entry.title, + fontSize = 15.sp, + fontWeight = FontWeight.SemiBold, + color = IosColors.Label, + modifier = Modifier.weight(1f), + ) Text( - text = "Solana Explorer: https://explorer.solana.com/tx/$signature?cluster=devnet", - style = MaterialTheme.typography.bodySmall, + text = entry.time, + fontSize = 12.sp, + fontFamily = FontFamily.Monospace, + color = IosColors.SecondaryLabel, + ) + } + entry.signature?.let { sig -> + Text( + text = sig, + fontSize = 13.sp, + fontFamily = FontFamily.Monospace, + color = IosColors.Label, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + Text( + text = "View receipt on pay.sh", + fontSize = 13.sp, + fontWeight = FontWeight.Normal, + color = IosColors.Blue, + modifier = Modifier.clickableNoRipple { + val uri = Uri.parse("https://pay.sh/receipt/$sig?network=sandbox") + runCatching { context.startActivity(Intent(Intent.ACTION_VIEW, uri)) } + }, + ) + } + entry.detail?.let { detail -> + Text( + text = detail, + fontSize = 13.sp, + fontFamily = if (entry.monoDetail) FontFamily.Monospace else FontFamily.Default, + color = IosColors.SecondaryLabel, + maxLines = entry.detailMaxLines, + overflow = TextOverflow.Ellipsis, ) } } } -private data class Status( - val inFlight: Boolean, - val message: String, +/** Clickable without the Material ripple, to keep the surrounding cells clean. */ +@Composable +private fun Modifier.clickableNoRipple(enabled: Boolean = true, onClick: () -> Unit): Modifier { + val interactionSource = remember { MutableInteractionSource() } + return this.clickable( + interactionSource = interactionSource, + indication = null, + enabled = enabled, + onClick = onClick, + ) +} + +// endregion + +// region Log model + +private data class LogEntry( + val title: String, + val time: String, + val statusIcon: ImageVector, + val statusTint: Color, val signature: String? = null, + val detail: String? = null, + val monoDetail: Boolean = true, + val detailMaxLines: Int = 6, ) { companion object { - fun idle() = Status(false, "Idle. Press Connect Wallet to begin.") - fun running(message: String = "Working ...") = Status(true, message) + private val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.US) + + private fun now(): String = timeFormat.format(Date()) + + fun success(endpoint: Endpoint, signature: String?, body: String): LogEntry = LogEntry( + title = "${endpoint.label} — 200 OK", + time = now(), + statusIcon = Icons.Filled.Verified, + statusTint = IosColors.Green, + signature = signature, + detail = when { + body.isNotBlank() -> body + signature == null -> "Settled. No settlement signature in response." + else -> null + }, + detailMaxLines = 4, + ) + + fun failure(endpoint: Endpoint?, message: String): LogEntry = LogEntry( + title = endpoint?.let { "${it.label} — failed" } ?: "Error", + time = now(), + statusIcon = Icons.Filled.Dangerous, + statusTint = IosColors.Red, + detail = message, + detailMaxLines = 6, + ) + + fun system(message: String, success: Boolean): LogEntry = LogEntry( + title = "System", + time = now(), + statusIcon = if (success) Icons.Filled.Info else Icons.Filled.Warning, + statusTint = if (success) IosColors.Blue else IosColors.Orange, + detail = message, + monoDetail = false, + ) } } +private sealed interface BusyKind { + data object Topup : BusyKind + data class Pay(val endpointId: String) : BusyKind +} + +// endregion + +// region iOS-like palette + +private object IosColors { + val GroupedBackground = Color(0xFFF2F2F7) + val Card = Color(0xFFFFFFFF) + val Label = Color(0xFF000000) + val SecondaryLabel = Color(0xFF8E8E93) + val Separator = Color(0xFFC6C6C8) + val Blue = Color(0xFF007AFF) + val Green = Color(0xFF34C759) + val Red = Color(0xFFFF3B30) + val Orange = Color(0xFFFF9500) +} + +// endregion + +// region Consume flow (SDK) + private val responseJson = Json { ignoreUnknownKeys = true } private val httpClient = OkHttpClient() /** - * Issues the initial unauthenticated GET, parses the 402 challenge, - * builds the unsigned transaction, asks the wallet to sign it, and - * replays the request with the MPP Authorization header. - * - * Runs the OkHttp/JSON-RPC calls on Dispatchers.IO so they do not block - * the compose recomposition thread. The walletAdapter.transact call - * itself suspends on the wallet's user-approval flow. + * Consumes a priced endpoint through the unified [PayKitClient], mirroring the + * iOS demo's `pay(_:)`. Builds an MPP-charge-enabled client bound to the + * persisted signer, issues the request against `PLAYGROUND_BASE + endpoint.path`, + * and lets the charge interceptor run the 402 -> pay -> retry loop. The on-chain + * signature is pulled from the `Payment-Receipt` envelope on success. */ -private suspend fun runCharge( - walletAdapter: MobileWalletAdapter, - sender: ActivityResultSender, - walletPubkey: PublicKey, - merchantUrl: String, - rpcUrl: String, -): Status { - return try { - // 1. Initial GET. Expect 402 with a Solana charge challenge. - // Read everything that touches the response body off the main thread - // so okhttp's lazy body consumption does not raise - // NetworkOnMainThreadException on resume. - data class InitialResponse(val code: Int, val body: String, val wwwAuth: List) - val initialParsed = withContext(Dispatchers.IO) { - httpClient.newCall(Request.Builder().url(merchantUrl).get().build()).execute().use { resp -> - InitialResponse( - code = resp.code, - body = resp.body?.string().orEmpty(), - wwwAuth = resp.headers("WWW-Authenticate"), - ) - } - } - if (initialParsed.code != 402) { - return Status(false, "Expected 402, got HTTP ${initialParsed.code}\n${initialParsed.body}") +/** + * Drive the full payment-channel **session** for a session endpoint: open the + * channel, stream the metered SSE deliveries, sign + commit a voucher, and poll + * the settle signature (see [SessionStream]). Mirrors the iOS demo's session path. + */ +private suspend fun consumeSession(signer: SolanaSigner, endpoint: Endpoint): LogEntry = withContext(Dispatchers.IO) { + try { + val client = OkHttpClient.Builder() + .readTimeout(60, java.util.concurrent.TimeUnit.SECONDS) + .build() + val result = SessionStream.consume(client, "$PLAYGROUND_BASE${endpoint.path}", signer) + LogEntry.success( + endpoint = endpoint, + signature = result.settleSignature, + body = result.steps.joinToString("\n"), + ) + } catch (t: Throwable) { + android.util.Log.e("PayKitDemo", "session consume failed", t) + LogEntry.failure(endpoint, "${t.javaClass.simpleName}: ${t.message ?: "(no message)"}") + } +} + +private suspend fun consume(signer: SolanaSigner, endpoint: Endpoint, protocol: String?): LogEntry = withContext(Dispatchers.IO) { + val url = "$PLAYGROUND_BASE${endpoint.path}" + try { + // Settle over the protocol the user picked (default: the advertised mpp). + val client = if (protocol == "x402") { + PayKitClient.Builder().signer(signer).x402(rpc = RPC_URL, network = "devnet").build() + } else { + PayKitClient.Builder().signer(signer).charge(blockhashProvider = JsonRpcClient(RPC_URL)).build() } - val challengeHeaders = initialParsed.wwwAuth - val challenge = MppHeaders.selectSolanaChargeChallenge(challengeHeaders) - ?: throw MppException.InvalidPaymentScheme - - // 2. Build the unsigned transaction with the wallet's pubkey as - // signer. JsonRpcClient supplies the recent blockhash if the - // challenge does not pin one. - val unsignedTx = withContext(Dispatchers.IO) { - Charge.buildUnsignedChargeTransaction( - walletPublicKey = walletPubkey, - request = challenge.chargeRequest(), - blockhashProvider = JsonRpcClient(rpcUrl), + + val payResponse = if (endpoint.method == "POST") { + client.post( + url = url, + body = "{}".toByteArray(), + contentType = "application/json", + headers = mapOf("Accept" to "application/json"), ) + } else { + client.get(url = url, headers = mapOf("Accept" to "application/json")) } - // 3. Ask the wallet to sign. MWA returns the signed transaction - // wire bytes directly; we base64-encode for the credential. - val signResult = walletAdapter.transact(sender) { authResult -> - // Confirm the connected account still matches the one we - // built the transaction against. If the user switched - // accounts inside the wallet, the wire bytes reference the - // wrong fee payer and the signature would be rejected on - // submission. - val authPubkey = PublicKey(authResult.accounts.first().publicKey) - check(authPubkey.bytes.contentEquals(walletPubkey.bytes)) { - "wallet returned a different account than the one used to build the transaction" - } - signTransactions(arrayOf(unsignedTx)) - } - val signedTxBytes = when (signResult) { - is TransactionResult.Success -> - signResult.successPayload?.signedPayloads?.firstOrNull() - ?: return Status(false, "Wallet returned no signed payload") - is TransactionResult.NoWalletFound -> - return Status(false, "No wallet found on device") - is TransactionResult.Failure -> - return Status( - false, - "Wallet sign failed: ${signResult.e.message ?: signResult.e::class.simpleName}", + val settlement = payResponse.settlement + payResponse.use { body -> + val text = body.orEmpty() + if (payResponse.status in 200..299) { + LogEntry.success( + endpoint = endpoint, + // Decode the settlement envelope; if it isn't a recognized + // envelope, fall back to the raw header string (mirrors the + // Swift demo's `?? response.settlementSignature`). + signature = settlement?.let { signatureFromReceiptHeader(it) ?: it.takeIf { s -> s.isNotEmpty() } }, + body = text, ) - } - val signedTxBase64 = JBase64.getEncoder().encodeToString(signedTxBytes) - - // 4. Replay the request with the Authorization header. - val authorization = MppHeaders.formatAuthorization( - PaymentCredential( - challenge = challenge.echo(), - payload = CredentialPayload.transaction(signedTxBase64), - ), - ) - data class AuthedResponse(val code: Int, val body: String) - val authed = withContext(Dispatchers.IO) { - httpClient.newCall( - Request.Builder().url(merchantUrl).get() - .header("Authorization", authorization) - .build(), - ).execute().use { resp -> - AuthedResponse(resp.code, resp.body?.string().orEmpty()) + } else { + LogEntry.failure(endpoint, "HTTP ${payResponse.status}\n$text") } } - val code = authed.code - val body = authed.body - Status( - inFlight = false, - message = "HTTP $code\n$body", - signature = extractSignature(body), - ) } catch (mpp: MppException) { - android.util.Log.e("MppDemo", "MPP error", mpp) - Status(false, "MPP error: ${mpp.message ?: mpp::class.simpleName}") + android.util.Log.e("PayKitDemo", "MPP error", mpp) + LogEntry.failure(endpoint, "MPP error: ${mpp.message ?: mpp::class.simpleName}") } catch (t: Throwable) { - android.util.Log.e("MppDemo", "runCharge failed", t) - Status(false, "Error: ${t.javaClass.simpleName}: ${t.message ?: "(no message)"}") + android.util.Log.e("PayKitDemo", "consume failed", t) + LogEntry.failure(endpoint, "${t.javaClass.simpleName}: ${t.message ?: "(no message)"}") } } -private fun extractSignature(body: String): String? { - if (body.isBlank()) return null +/** + * Decode a settlement header (base64url-no-pad JSON envelope) and return the + * on-chain signature. MPP's `Payment-Receipt` carries it in `reference`; + * x402's `X-PAYMENT-RESPONSE` carries it in `transaction`. Mirrors the iOS + * `signatureFromReceiptHeader`. + */ +private fun signatureFromReceiptHeader(header: String): String? { return try { - val parsed = responseJson.parseToJsonElement(body) - val obj = parsed as? JsonObject ?: return null - // Spine receipts surface the on-chain signature under different - // key names depending on the server. Try the common shapes. - listOf("signature", "tx_signature", "txSignature") - .firstNotNullOfOrNull { obj[it]?.jsonPrimitive?.content } - ?: obj["receipt"]?.let { (it as? JsonObject) }?.let { receipt -> - listOf("signature", "tx_signature", "txSignature") - .firstNotNullOfOrNull { receipt[it]?.jsonPrimitive?.content } - } + // MPP's `Payment-Receipt` is base64url; x402's `X-PAYMENT-RESPONSE` is + // standard base64 (`btoa`). Normalize to url-safe so one decoder fits both. + val normalized = header.replace('+', '-').replace('/', '_').trimEnd('=') + val decoded = JBase64.getUrlDecoder().decode(normalized.padBase64Url()) + val json = responseJson.parseToJsonElement(String(decoded)) as? JsonObject ?: return null + // MPP's `Payment-Receipt` carries the on-chain signature in `reference`; + // x402's `X-PAYMENT-RESPONSE` carries it in `transaction`. + (json["reference"] ?: json["transaction"])?.jsonPrimitive?.contentOrNull?.takeIf { it.isNotEmpty() } } catch (_: Throwable) { null } } + +private fun String.padBase64Url(): String { + val pad = (4 - length % 4) % 4 + return this + "=".repeat(pad) +} + +// endregion + +// region OpenAPI fetch + +/** Fetch and parse the playground's `/openapi.json` off the main thread. */ +private suspend fun fetchEndpoints(): List = withContext(Dispatchers.IO) { + val request = Request.Builder().url("$PLAYGROUND_BASE/openapi.json").get().build() + httpClient.newCall(request).execute().use { resp -> + val body = resp.body?.string().orEmpty() + if (resp.code !in 200..299) { + throw OpenApiException("openapi.json returned HTTP ${resp.code}") + } + OpenApi.endpoints(body) + } +} + +// endregion + +// region Account store + topup/balance + +/** Surfpool sandbox cheatcode targets and demo topup amounts (mirror DemoSigner.swift). */ +private const val USDC_MINT = Mints.USDC_MAINNET +private const val SYSTEM_PROGRAM = "11111111111111111111111111111111" +private const val TOPUP_LAMPORTS = 100_000_000_000L +private const val TOPUP_USDC_BASE_UNITS = 1_000_000_000L + +/** + * Persists the demo signer's 32 byte Ed25519 seed in SharedPreferences (the + * Android analogue of the iOS Keychain store). DEMO ONLY: the key is in + * cleartext app storage; production apps should use the Android Keystore or a + * wallet-backed [SolanaSigner]. + */ +private class AccountStore(context: Context) { + private val prefs: SharedPreferences = + context.getSharedPreferences("paykit-demo", Context.MODE_PRIVATE) + + /** Load the persisted signer, or null when Setup Account has not run. */ + fun loadSigner(): SolanaSigner? { + val encoded = prefs.getString(SEED_KEY, null) ?: return null + val seed = JBase64.getDecoder().decode(encoded) + require(seed.size == 32) { "stored seed is not 32 bytes; reset the account" } + return MemorySigner.fromSeed(seed) + } + + /** Generate a fresh signer, persist its seed, and return it. */ + fun setupSigner(): SolanaSigner { + val signer = MemorySigner.generate() + prefs.edit().putString(SEED_KEY, JBase64.getEncoder().encodeToString(signer.seedBytes())).apply() + return signer + } + + private companion object { + const val SEED_KEY = "demo-signer-seed" + } +} + +/** + * Seed an account on Surfpool with SOL + USDC via the surfnet cheatcodes. + * Idempotent — re-running just resets the balances. Only works on a Surfpool + * RPC (the hosted sandbox or local Surfpool). + */ +private suspend fun topup(rpcUrl: String, pubkey: String) = withContext(Dispatchers.IO) { + rpcCall( + rpcUrl, + method = "surfnet_setAccount", + params = buildJsonArray { + add(JsonPrimitive(pubkey)) + add( + buildJsonObject { + put("lamports", TOPUP_LAMPORTS) + put("data", "") + put("executable", false) + put("owner", SYSTEM_PROGRAM) + }, + ) + }, + ) + rpcCall( + rpcUrl, + method = "surfnet_setTokenAccount", + params = buildJsonArray { + add(JsonPrimitive(pubkey)) + add(JsonPrimitive(USDC_MINT)) + add(buildJsonObject { put("amount", TOPUP_USDC_BASE_UNITS) }) + add(JsonPrimitive(Programs.TOKEN_PROGRAM)) + }, + ) +} + +/** + * Fetch the USDC balance (in decimal USDC, 6-decimal mint) for [pubkey] on the + * given Surfpool RPC. Returns null when the ATA does not exist yet (the account + * has not been topped up). Mirrors `DemoSigner.usdcBalance`. + */ +private suspend fun usdcBalance(rpcUrl: String, pubkey: String): BigDecimal? = withContext(Dispatchers.IO) { + val ata = Pda.associatedTokenAddress( + owner = PublicKey.fromBase58(pubkey), + mint = PublicKey.fromBase58(USDC_MINT), + tokenProgram = PublicKey.fromBase58(Programs.TOKEN_PROGRAM), + ) + val response = try { + rpcCall( + rpcUrl, + method = "getTokenAccountBalance", + params = buildJsonArray { add(JsonPrimitive(ata.toBase58())) }, + ) + } catch (e: Throwable) { + if (e.message?.contains("could not find account") == true) return@withContext null + throw e + } + val ui = response["result"]?.jsonObject?.get("value")?.jsonObject + ?.get("uiAmountString")?.jsonPrimitive?.contentOrNull + ?: return@withContext null + ui.toBigDecimalOrNull() +} + +/** Minimal JSON-RPC POST; throws on a JSON-RPC `error` field or non-2xx status. */ +private fun rpcCall( + rpcUrl: String, + method: String, + params: kotlinx.serialization.json.JsonArray, +): JsonObject { + val payload = buildJsonObject { + put("jsonrpc", "2.0") + put("id", 1) + put("method", method) + put("params", params) + } + val body = responseJson.encodeToString(JsonObject.serializer(), payload) + .toRequestBody("application/json".toMediaType()) + val request = Request.Builder().url(rpcUrl).post(body).build() + httpClient.newCall(request).execute().use { resp -> + val text = resp.body?.string().orEmpty() + if (resp.code !in 200..299) { + throw IllegalStateException("RPC HTTP ${resp.code}: $text") + } + val parsed = responseJson.parseToJsonElement(text) as? JsonObject + ?: throw IllegalStateException("non-object RPC response") + parsed["error"]?.let { throw IllegalStateException("RPC error: $it") } + return parsed + } +} + +private fun String.toBigDecimalOrNull(): BigDecimal? = + try { + BigDecimal(this) + } catch (_: NumberFormatException) { + null + } + +// region formatting helpers + +/** Truncate a base58 pubkey to `first6…last6`, like the iOS `shortAddress`. */ +private fun shortAddress(address: String): String = + if (address.length > 14) "${address.take(6)}…${address.takeLast(6)}" else address + +/** Format a USDC decimal, trimming trailing zeros (max 6 fraction digits). */ +private fun formatUsdc(amount: BigDecimal): String { + val stripped = amount.stripTrailingZeros() + return if (stripped.scale() <= 0) stripped.toBigInteger().toString() else stripped.toPlainString() +} + +// endregion diff --git a/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/OpenApi.kt b/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/OpenApi.kt new file mode 100644 index 000000000..e3916d347 --- /dev/null +++ b/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/OpenApi.kt @@ -0,0 +1,250 @@ +package com.solana.paykit.demo + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Bolt +import androidx.compose.material.icons.filled.CreditCard +import androidx.compose.material.icons.filled.Repeat +import androidx.compose.material.icons.filled.Sensors +import androidx.compose.material.icons.filled.Speed +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import java.math.BigDecimal +import java.math.RoundingMode + +/** + * A priced operation discovered from the playground's `/openapi.json`, + * rendered as a tappable card in the endpoints collection. Mirrors the + * iOS demo's `Endpoint` value type. + */ +data class Endpoint( + val id: String, + val label: String, + val method: String, + val path: String, + val priceUsd: String, + val icon: ImageVector, + val tint: Color, + /** Discovery intent of the first offer (`charge` / `session` / …). */ + val intent: String, + /** Accepted protocols in offer order, e.g. `["x402", "mpp"]`. */ + val methods: List, + /** The protocol this demo settles over (`mpp` for charge endpoints that + * advertise it); `null` for flows it doesn't consume. Rendered emphasized + * on the card so it's clear which offer is used. */ + val selectedProtocol: String?, +) + +/** Vertical-gradient bottom stop: the tint darkened ~12% (mirrors the iOS + * `Color.gradient` shading used on the endpoint cards). */ +fun Color.darkenBy(fraction: Float = 0.12f): Color { + val k = 1f - fraction + return Color(red = red * k, green = green * k, blue = blue * k, alpha = alpha) +} + +/** + * Decodes the playground's `GET /openapi.json` discovery document into the + * app's `List` collection. + * + * The document is an OpenAPI 3.1 doc whose every priced operation under + * `paths..` carries an `x-payment-info` extension with an + * `offers[]` list (the payment-discovery draft: `intent` / `method` / `amount` + * per offer, plus pay-kit extras like `scheme` / `network` / `payTo`). + * Operations with no `x-payment-info` (health, `/openapi.json`, docs) are free + * and excluded. + * + * Parsing goes through `kotlinx.serialization`'s untyped `JsonObject` tree + * (with `ignoreUnknownKeys`) rather than `@Serializable` data classes, because + * the hyphenated extension keys and arbitrarily-nested offers array are awkward + * for generated decoders. This mirrors the iOS demo's `JSONSerialization` path. + */ +object OpenApi { + private val json = Json { ignoreUnknownKeys = true } + + /** HTTP verbs that can carry an operation object in an OpenAPI path item. */ + private val HTTP_METHODS = setOf("get", "post", "put", "patch", "delete", "head", "options") + + /** + * Cycle through a fixed palette so each card gets a distinct tint. Matches + * the iOS palette order so the two demos read the same. + */ + private val PALETTE = listOf( + Color(0xFF007AFF), // blue + Color(0xFF5E5CE6), // indigo + Color(0xFFFF2D55), // pink/magenta + Color(0xFF34C759), // green + Color(0xFFFF9500), // orange + Color(0xFFAF52DE), // purple + Color(0xFFFF3B30), // red + Color(0xFF5AC8FA), // teal/cyan + ) + + /** + * Build the priced-endpoint collection from a raw `/openapi.json` body. + * Returns endpoints in a stable order (sorted by path then method) so the + * per-index tint and layout do not reshuffle between loads. + */ + fun endpoints(from: String): List { + val root = json.parseToJsonElement(from).jsonObject + val paths = root["paths"]?.jsonObject ?: throw OpenApiException("openapi.json had no `paths`.") + + data class Parsed(val path: String, val method: String, val operation: JsonObject) + + val parsed = mutableListOf() + for ((path, item) in paths) { + val operations = item as? JsonObject ?: continue + for ((method, op) in operations) { + if (method.lowercase() !in HTTP_METHODS) continue + val operation = op as? JsonObject ?: continue + // Only priced operations are tappable. Free routes (health, + // docs, /openapi.json) carry no `x-payment-info`. + operation["x-payment-info"] as? JsonObject ?: continue + parsed.add(Parsed(path, method.uppercase(), operation)) + } + } + + parsed.sortWith(compareBy({ it.path }, { it.method })) + + return parsed.mapIndexed { index, entry -> + endpoint(entry.path, entry.method, entry.operation, index) + } + } + + private fun endpoint(path: String, method: String, operation: JsonObject, index: Int): Endpoint { + val paymentInfo = operation["x-payment-info"]?.jsonObject + val offers = paymentInfo?.get("offers")?.jsonArray + val firstOffer = offers?.firstOrNull()?.jsonObject + + val summary = (operation["summary"] as? JsonPrimitive)?.contentOrNull?.trim() + val label = if (!summary.isNullOrEmpty()) summary else path + + val intent = (firstOffer?.get("intent") as? JsonPrimitive)?.contentOrNull + val scheme = (firstOffer?.get("scheme") as? JsonPrimitive)?.contentOrNull + val payMethod = (firstOffer?.get("method") as? JsonPrimitive)?.contentOrNull + + return Endpoint( + id = "$method $path", + label = label, + method = method, + path = requestPath(path), + priceUsd = priceString(firstOffer), + icon = iconFor(intent = intent, scheme = scheme, method = payMethod), + tint = PALETTE[index % PALETTE.size], + intent = if (!intent.isNullOrEmpty()) intent.lowercase() else "charge", + methods = methodsOf(offers), + selectedProtocol = selectedProtocol(offers, intent), + ) + } + + /** Accepted protocols (offer `method`s) de-duplicated in offer order. */ + private fun methodsOf(offers: kotlinx.serialization.json.JsonArray?): List { + val methods = LinkedHashSet() + offers?.forEach { offer -> + ((offer as? JsonObject)?.get("method") as? JsonPrimitive)?.contentOrNull + ?.takeIf { it.isNotEmpty() }?.let { methods.add(it) } + } + return methods.toList() + } + + /** The protocol the demo settles over: it drives charge endpoints through the + * MPP client, so `mpp` is selected when a charge endpoint advertises it. */ + private fun selectedProtocol(offers: kotlinx.serialization.json.JsonArray?, intent: String?): String? { + if ((intent?.lowercase() ?: "charge") != "charge") return null + val ms = methodsOf(offers) + return if (ms.contains("mpp")) "mpp" else ms.firstOrNull() + } + + /** + * Pick a Material icon by payment intent/scheme/method, mirroring the iOS + * demo's `systemImage(intent:scheme:method:)` so the cards carry the same + * glyph as Swift (every `charge` endpoint shows the credit-card icon): + * charge -> CreditCard, session -> Sensors, subscription -> Repeat, + * usage -> Speed; else by scheme (exact -> Bolt, upto -> Speed); + * else x402 -> Bolt, otherwise CreditCard. + */ + private fun iconFor(intent: String?, scheme: String?, method: String?): ImageVector { + when (intent?.lowercase()) { + "charge" -> return Icons.Filled.CreditCard + "session" -> return Icons.Filled.Sensors + "subscription" -> return Icons.Filled.Repeat + "usage" -> return Icons.Filled.Speed + } + when (scheme?.lowercase()) { + "exact" -> return Icons.Filled.Bolt + "upto" -> return Icons.Filled.Speed + "subscription" -> return Icons.Filled.Repeat + "session" -> return Icons.Filled.Sensors + } + return if (method?.lowercase() == "x402") Icons.Filled.Bolt else Icons.Filled.CreditCard + } + + /** + * Turn a templated OpenAPI path (`/api/v1/quote/{symbol}`) into a concrete + * request path by filling each `{param}` with a `demo` placeholder, so the + * URL reaches the mounted route instead of 404-ing on the literal + * `{symbol}` segment. + */ + fun requestPath(openApiPath: String): String { + if (!openApiPath.contains('{')) return openApiPath + val result = StringBuilder() + var insideParam = false + for (char in openApiPath) { + when (char) { + '{' -> { + insideParam = true + result.append("demo") + } + '}' -> insideParam = false + else -> if (!insideParam) result.append(char) + } + } + return result.toString() + } + + /** + * Format the offer price as a dollar string. The offer's `amount` is a + * base-unit integer string (USDC has 6 decimals); fall back to the + * human-readable `description` (e.g. `"0.01 USDC"`) and finally a dash. + */ + fun priceString(offer: JsonObject?): String { + val amount = (offer?.get("amount") as? JsonPrimitive)?.contentOrNull + val baseUnits = amount?.toBigDecimalOrNull() + if (baseUnits != null) { + val dollars = baseUnits + .divide(BigDecimal(1_000_000)) + .setScale(2, RoundingMode.HALF_UP) + .stripTrailingZerosOrTwo() + // `upto` usage and `session` deposits are ceilings, not the amount + // actually settled — label them so the price isn't read as a fixed charge. + val scheme = (offer["scheme"] as? JsonPrimitive)?.contentOrNull?.lowercase() + val prefix = if (scheme == "upto" || scheme == "session") "up to " else "" + return "$prefix$$dollars" + } + val description = (offer?.get("description") as? JsonPrimitive)?.contentOrNull + if (!description.isNullOrEmpty()) return description + return "—" + } + + private fun String.toBigDecimalOrNull(): BigDecimal? = + try { + BigDecimal(this) + } catch (_: NumberFormatException) { + null + } + + /** Keep at least 2 fraction digits (so `$0.01`), but allow more when present. */ + private fun BigDecimal.stripTrailingZerosOrTwo(): String { + val stripped = stripTrailingZeros() + val scale = stripped.scale().coerceAtLeast(2) + return stripped.setScale(scale, RoundingMode.HALF_UP).toPlainString() + } +} + +/** Failure mode when decoding `/openapi.json`. */ +class OpenApiException(message: String) : Exception(message) diff --git a/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/SessionStream.kt b/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/SessionStream.kt new file mode 100644 index 000000000..8e22a055a --- /dev/null +++ b/kotlin/examples/AndroidDemo/app/src/main/java/com/solana/paykit/demo/SessionStream.kt @@ -0,0 +1,199 @@ +package com.solana.paykit.demo + +import com.solana.paykit.paycore.MemorySigner +import com.solana.paykit.paycore.MppException +import com.solana.paykit.paycore.SolanaSigner +import com.solana.paykit.protocols.mpp.client.CommitTransport +import com.solana.paykit.protocols.mpp.client.PaymentChannelSession +import com.solana.paykit.protocols.mpp.client.SessionConsumer +import com.solana.paykit.protocols.mpp.core.CommitPayload +import com.solana.paykit.protocols.mpp.core.CommitReceipt +import com.solana.paykit.protocols.mpp.core.MeteringDirective +import com.solana.paykit.protocols.mpp.core.MppHeaders +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.put +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import java.security.SecureRandom +import java.util.UUID + +/** + * Drives a full MPP payment-channel **session** against the playground's + * `/api/v1/stream` (a metered SSE endpoint) — the flow the one-shot charge + * client can't do. Mirrors the iOS `SessionStream`: + * + * 1. GET unauthenticated -> 402 `WWW-Authenticate` session challenge. + * 2. Open the channel: `PaymentChannelSession.open` builds the payer-signed + * open tx; the credential carries it and the server (operator) co-signs + + * broadcasts. Retrying the GET with that credential returns the SSE stream. + * 3. Read the SSE deliveries (`data: {chunk,cost}` ... `[DONE]`), summing cost. + * 4. Reserve a delivery on the side channel, then sign + commit one cumulative + * voucher through `SessionConsumer`. + * 5. Poll the receipt route for the on-chain settle signature. + * + * Synchronous (blocking OkHttp); call it off the main thread. + */ +object SessionStream { + data class Result( + val channelId: String, + val chunks: Int, + val totalPaidBaseUnits: Long, + val cumulative: String, + val settleSignature: String?, + /** Ordered trace of each step's output, surfaced in the log so the flow + * is visible (open -> stream -> commit -> settle). */ + val steps: List, + ) + + private val json = Json { + ignoreUnknownKeys = true + encodeDefaults = false + explicitNulls = false + } + private val JSON_MEDIA = "application/json".toMediaType() + + fun consume(client: OkHttpClient, streamUrl: String, payer: SolanaSigner): Result { + val steps = mutableListOf() + // 1. Unauthenticated GET -> 402 session challenge. + val challenge = client.newCall( + Request.Builder().url(streamUrl).header("Accept", "application/json").get().build() + ).execute().use { resp -> + if (resp.code != 402) error("expected 402 from stream, got ${resp.code}") + val header = resp.header("WWW-Authenticate") ?: error("402 had no WWW-Authenticate header") + MppHeaders.parseWWWAuthenticate(header) + } + PaymentChannelSession.requireSolanaSession(challenge) + val request = PaymentChannelSession.sessionRequest(challenge) + val blockhash = request.recentBlockhash + require(!blockhash.isNullOrEmpty()) { "session challenge did not carry a recentBlockhash" } + + // 2. Open the channel (pull + clientVoucher, server-broadcast). + val sessionSigner = MemorySigner.fromSeed(randomSeed()) + val opener = PaymentChannelSession.open(request, payer, sessionSigner, blockhash) + val channelId = opener.open.channelId.toBase58() + val credential = PaymentChannelSession.serializeSessionCredential(challenge.echo(), opener.action) + steps.add("opened channel ${shortId(channelId)} · deposit ${usd(request.cap)}") + + // 3. Retry the GET with the open credential -> 200 SSE; read deliveries. + var chunks = 0 + var total = 0L + client.newCall( + Request.Builder().url(streamUrl) + .header("Authorization", credential) + .header("Accept", "text/event-stream") + .get().build() + ).execute().use { resp -> + if (!resp.isSuccessful) error("stream open failed: HTTP ${resp.code}") + val reader = resp.body?.charStream()?.buffered() ?: error("stream had no body") + while (true) { + val line = reader.readLine() ?: break + if (!line.startsWith("data:")) continue + val payload = line.removePrefix("data:").trim() + if (payload == "[DONE]") break + val obj = runCatching { json.parseToJsonElement(payload).jsonObject }.getOrNull() ?: continue + chunks++ + (obj["cost"] as? JsonPrimitive)?.contentOrNull?.toLongOrNull()?.let { total += it } + } + } + steps.add("streamed $chunks chunks · metered ${usd(total)}") + + // 4. Reserve one aggregate delivery, then sign + commit the voucher. + var cumulative = "0" + if (total > 0) { + val directive = reserveDelivery(client, sideChannel(streamUrl, "/__402/session/deliveries"), channelId, total, streamUrl) + val consumer = SessionConsumer(opener.session, HttpCommitTransport(client, sideChannel(streamUrl, "/__402/session/commit"))) + val receipt = consumer.commitDirective(directive) + cumulative = receipt.cumulative + steps.add("committed voucher · cumulative ${receipt.cumulative} (${receipt.status.name.lowercase()})") + } + + // 5. Best-effort receipt poll for the settle signature. + val settle = runCatching { pollReceipt(client, sideChannel(streamUrl, "/sessions/receipt/$channelId")) }.getOrNull() + steps.add(if (settle != null) "settled on-chain · ${shortId(settle)}" else "settle pending (idle-close runs server-side)") + + return Result(channelId, chunks, total, cumulative, settle, steps) + } + + private fun shortId(value: String): String = + if (value.length > 14) "${value.take(6)}…${value.takeLast(6)}" else value + + private fun usd(baseUnits: Long): String = + "$" + java.math.BigDecimal(baseUnits).divide(java.math.BigDecimal(1_000_000)).stripTrailingZeros().toPlainString() + + private fun usd(baseUnitsString: String): String = + baseUnitsString.toLongOrNull()?.let { usd(it) } ?: baseUnitsString + + private fun reserveDelivery( + client: OkHttpClient, + url: String, + channelId: String, + amount: Long, + commitUrl: String, + ): MeteringDirective { + val body = buildJsonObject { + put("amount", amount.toString()) + put("sessionId", channelId) + put("deliveryId", "mpp-${UUID.randomUUID()}") + put("commitUrl", commitUrl) + } + val req = Request.Builder().url(url) + .header("Accept", "application/json") + .post(json.encodeToString(JsonObject.serializer(), body).toRequestBody(JSON_MEDIA)) + .build() + return client.newCall(req).execute().use { resp -> + if (!resp.isSuccessful) error("delivery reservation failed: HTTP ${resp.code}") + json.decodeFromString(MeteringDirective.serializer(), resp.body!!.string()) + } + } + + private fun pollReceipt(client: OkHttpClient, url: String): String? { + repeat(8) { + Thread.sleep(1_500) + val obj = client.newCall(Request.Builder().url(url).get().build()).execute().use { resp -> + if (!resp.isSuccessful) return@use null + runCatching { json.parseToJsonElement(resp.body!!.string()).jsonObject }.getOrNull() + } ?: return@repeat + val finalized = (obj["finalized"] as? JsonPrimitive)?.contentOrNull == "true" + val sig = (obj["settledSignature"] as? JsonPrimitive)?.contentOrNull + if (finalized && !sig.isNullOrEmpty()) return sig + } + return null + } + + private fun sideChannel(streamUrl: String, path: String): String = + streamUrl.toHttpUrl().newBuilder().encodedPath(path).query(null).build().toString() + + private fun randomSeed(): ByteArray = ByteArray(32).also { SecureRandom().nextBytes(it) } +} + +/** Posts signed vouchers to `POST /__402/session/commit` and decodes the receipt. */ +private class HttpCommitTransport( + private val client: OkHttpClient, + private val commitUrl: String, +) : CommitTransport { + private val json = Json { encodeDefaults = false; explicitNulls = false; ignoreUnknownKeys = true } + private val media = "application/json".toMediaType() + + override fun commit(directive: MeteringDirective, payload: CommitPayload): CommitReceipt { + val req = Request.Builder().url(commitUrl) + .header("Accept", "application/json") + .post(json.encodeToString(CommitPayload.serializer(), payload).toRequestBody(media)) + .build() + return client.newCall(req).execute().use { resp -> + if (!resp.isSuccessful) { + throw MppException.InvalidTransaction( + "voucher commit failed: HTTP ${resp.code} ${resp.body?.string().orEmpty()}" + ) + } + json.decodeFromString(CommitReceipt.serializer(), resp.body!!.string()) + } + } +} diff --git a/kotlin/examples/AndroidDemo/docs/android-demo-screenshot.png b/kotlin/examples/AndroidDemo/docs/android-demo-screenshot.png index b1903e38a61ccc2dfb7cd1ab7b16e1c87ffe7495..c782a40bf1f5cd04fd3f60bf8b97e8968c53c7c5 100644 GIT binary patch literal 254664 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

accept(envelope: MeteredEnvelope

): MeteredDelivery

{ + validateDirective(envelope.metering) + return MeteredDelivery(this, envelope.payload, envelope.metering) + } + + /** + * Sign a voucher for the directive amount, commit it, and advance the + * watermark. Rejects a mismatched session, a non-integer amount, or a zero + * amount before committing. On a committed receipt the prepared voucher is + * recorded; on a replayed receipt the watermark reconciles to the settled + * cumulative, clamped to the just-prepared voucher (server untrusted) and + * never regressing. + */ + fun commitDirective(directive: MeteringDirective): CommitReceipt { + validateDirective(directive) + val amount = directive.amountBaseUnits() + if (amount == 0uL) { + throw MppException.InvalidTransaction("metered delivery amount must be greater than zero") + } + + val voucher = session.prepareIncrement(amount) + val payload = CommitPayload(directive.deliveryId, voucher) + val receipt = transport.commit(directive, payload) + + when (receipt.status) { + CommitStatus.REPLAYED -> { + val settled = receipt.cumulative.toULongOrNull() + ?: throw MppException.InvalidTransaction("invalid replayed receipt cumulative: ${receipt.cumulative}") + val prepared = voucher.data.cumulative.toULongOrNull() + ?: throw MppException.InvalidTransaction("invalid prepared voucher cumulative: ${voucher.data.cumulative}") + session.reconcileSettled(minOf(settled, prepared)) + } + CommitStatus.COMMITTED -> session.recordVoucher(voucher) + } + return receipt + } + + private fun validateDirective(directive: MeteringDirective) { + val channelId = session.channelIdString() + if (directive.sessionId != channelId) { + throw MppException.InvalidTransaction( + "metered delivery session ${directive.sessionId} does not match active session $channelId" + ) + } + } +} + +/** + * A validated metered delivery awaiting acknowledgement. `ack`/`commit` sign and + * commit the voucher; `intoParts` releases the payload without committing. + */ +class MeteredDelivery

( + private val consumer: SessionConsumer, + val payload: P, + val metering: MeteringDirective, +) { + fun ack(): CommitReceipt = consumer.commitDirective(metering) + + fun commit(): CommitReceipt = ack() + + fun intoParts(): Pair = payload to metering +} diff --git a/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionActionCodec.kt b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionActionCodec.kt new file mode 100644 index 000000000..b47741752 --- /dev/null +++ b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionActionCodec.kt @@ -0,0 +1,59 @@ +package com.solana.paykit.protocols.mpp.core + +import com.solana.paykit.paycore.MppException +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.decodeFromJsonElement +import kotlinx.serialization.json.encodeToJsonElement +import kotlinx.serialization.json.jsonObject + +/** + * Codec for the internally-tagged [SessionAction] union: encodes the payload to + * a JSON object and injects the `action` discriminator alongside the payload's + * own fields (flattened), and decodes by reading `action` then the remaining + * fields. Mirrors the Rust serde internally-tagged enum and the Go SessionAction + * JSON. The TopUp tag is camelCase `topUp`. + */ +object SessionActionCodec { + private val json = Json { + encodeDefaults = false + explicitNulls = false + ignoreUnknownKeys = true + } + + fun toJsonObject(action: SessionAction): JsonObject { + val (tag, element) = when (action) { + is SessionAction.Open -> "open" to json.encodeToJsonElement(action.payload) + is SessionAction.Voucher -> "voucher" to json.encodeToJsonElement(action.payload) + is SessionAction.Commit -> "commit" to json.encodeToJsonElement(action.payload) + is SessionAction.TopUp -> "topUp" to json.encodeToJsonElement(action.payload) + is SessionAction.Close -> "close" to json.encodeToJsonElement(action.payload) + } + return buildJsonObject { + put("action", JsonPrimitive(tag)) + for ((key, value) in element.jsonObject) put(key, value) + } + } + + fun fromJsonObject(obj: JsonObject): SessionAction { + val tag = (obj["action"] as? JsonPrimitive)?.content + ?: throw MppException.InvalidJson() + val rest = JsonObject(obj.filterKeys { it != "action" }) + return when (tag) { + "open" -> SessionAction.Open(json.decodeFromJsonElement(OpenPayload.serializer(), rest)) + "voucher" -> SessionAction.Voucher(json.decodeFromJsonElement(VoucherPayload.serializer(), rest)) + "commit" -> SessionAction.Commit(json.decodeFromJsonElement(CommitPayload.serializer(), rest)) + "topUp" -> SessionAction.TopUp(json.decodeFromJsonElement(TopUpPayload.serializer(), rest)) + "close" -> SessionAction.Close(json.decodeFromJsonElement(ClosePayload.serializer(), rest)) + else -> throw MppException.InvalidTransaction("unknown session action: $tag") + } + } + + fun encodeToString(action: SessionAction): String = + json.encodeToString(JsonObject.serializer(), toJsonObject(action)) + + fun decodeFromString(text: String): SessionAction = + fromJsonObject(json.parseToJsonElement(text).jsonObject) +} diff --git a/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionTypes.kt b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionTypes.kt new file mode 100644 index 000000000..5f29a75c4 --- /dev/null +++ b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/core/SessionTypes.kt @@ -0,0 +1,230 @@ +package com.solana.paykit.protocols.mpp.core + +import com.solana.paykit.paycore.MppException +import com.solana.paykit.paycore.PaymentChannels +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.nullable +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonNames +import kotlinx.serialization.json.JsonNull +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.buildJsonObject + +/** + * MPP payment-channel session wire types, mirroring the Rust spine + * (`rust/crates/mpp/src/protocol/intents/session.rs`) and the Go reference + * tag-for-tag and key-for-key. JSON keys are camelCase; `salt` serializes as a + * decimal string (reads string-or-number); `VoucherData.cumulativeAmount` also + * reads the legacy `cumulative` alias; `SessionAction` is an internally-tagged + * union flattened onto the `action` key (handled by [SessionActionCodec]). + */ + +/** Default voucher/session expiry: 2100-01-01T00:00:00Z (under JS max-safe-int). */ +const val DEFAULT_SESSION_EXPIRES_AT: Long = 4_102_444_800L + +@Serializable +enum class SessionMode { + @SerialName("push") PUSH, + @SerialName("pull") PULL, +} + +@Serializable +enum class SessionPullVoucherStrategy { + @SerialName("clientVoucher") CLIENT_VOUCHER, + @SerialName("operatedVoucher") OPERATED_VOUCHER, +} + +@Serializable +enum class CommitStatus { + @SerialName("committed") COMMITTED, + @SerialName("replayed") REPLAYED, +} + +/** Serializes a nullable u64 salt as a decimal string; reads string or number. */ +object SaltStringSerializer : KSerializer { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("Salt", PrimitiveKind.STRING).nullable + + override fun serialize(encoder: Encoder, value: ULong?) { + if (value == null) encoder.encodeNull() else encoder.encodeString(value.toString()) + } + + override fun deserialize(decoder: Decoder): ULong? { + val input = decoder as? JsonDecoder + ?: return decoder.decodeString().toULongOrNull() + ?: throw MppException.InvalidJson() + return when (val element = input.decodeJsonElement()) { + is JsonNull -> null + is JsonPrimitive -> + // Read the raw content as ULong for both the string and number + // forms: a u64 salt above Long.MAX_VALUE (about half the range) + // would be lost via longOrNull when sent as a JSON number. + element.content.toULongOrNull() ?: throw MppException.InvalidJson() + else -> throw MppException.InvalidJson() + } + } +} + +@Serializable +data class SessionSplit(val recipient: String, val bps: Int) + +@Serializable +data class SessionRequest( + val cap: String, + val currency: String, + val decimals: Int? = null, + val network: String? = null, + val operator: String, + val recipient: String, + val splits: List = emptyList(), + val programId: String? = null, + val description: String? = null, + val externalId: String? = null, + val minVoucherDelta: String? = null, + val modes: List = emptyList(), + val pullVoucherStrategy: SessionPullVoucherStrategy? = null, + val recentBlockhash: String? = null, +) + +@Serializable +data class OpenPayload( + val mode: SessionMode, + val channelId: String? = null, + val deposit: String? = null, + val payer: String? = null, + val payee: String? = null, + val mint: String? = null, + @Serializable(with = SaltStringSerializer::class) val salt: ULong? = null, + val gracePeriod: Long? = null, + val transaction: String? = null, + val tokenAccount: String? = null, + val approvedAmount: String? = null, + val owner: String? = null, + val initMultiDelegateTx: String? = null, + val updateDelegationTx: String? = null, + val authorizedSigner: String, + val signature: String, +) { + companion object { + fun paymentChannel( + mode: SessionMode, + channelId: String, + deposit: String, + payer: String, + payee: String, + mint: String, + salt: ULong, + gracePeriod: UInt, + authorizedSigner: String, + signature: String, + ): OpenPayload = OpenPayload( + mode = mode, channelId = channelId, deposit = deposit, payer = payer, payee = payee, + mint = mint, salt = salt, gracePeriod = gracePeriod.toLong(), + authorizedSigner = authorizedSigner, signature = signature, + ) + + fun push(channelId: String, deposit: String, authorizedSigner: String, signature: String): OpenPayload = + OpenPayload( + mode = SessionMode.PUSH, channelId = channelId, deposit = deposit, + authorizedSigner = authorizedSigner, signature = signature, + ) + + fun pull( + tokenAccount: String, + approvedAmount: String, + owner: String, + authorizedSigner: String, + signature: String, + ): OpenPayload = OpenPayload( + mode = SessionMode.PULL, tokenAccount = tokenAccount, approvedAmount = approvedAmount, + owner = owner, authorizedSigner = authorizedSigner, signature = signature, + ) + } + + /** Attach the server/operator-broadcast open transaction (base64). */ + fun withTransaction(transaction: String): OpenPayload = copy(transaction = transaction) +} + +@Serializable +data class VoucherData( + val channelId: String, + @SerialName("cumulativeAmount") @JsonNames("cumulative") val cumulative: String, + val expiresAt: Long, + val nonce: Long? = null, +) { + /** The 48-byte Ed25519 preimage for this voucher. */ + fun messageBytes(): ByteArray { + val amount = cumulative.toULongOrNull() + ?: throw MppException.InvalidTransaction("invalid voucher cumulative: $cumulative") + return PaymentChannels.voucherMessageBytes(channelId, amount, expiresAt) + } +} + +@Serializable +data class SignedVoucher(val data: VoucherData, val signature: String) + +@Serializable +data class VoucherPayload(val voucher: SignedVoucher) + +@Serializable +data class CommitPayload(val deliveryId: String, val voucher: SignedVoucher) + +@Serializable +data class TopUpPayload(val channelId: String, val newDeposit: String, val signature: String) + +@Serializable +data class ClosePayload(val channelId: String, val voucher: SignedVoucher? = null) + +@Serializable +data class MeteringDirective( + val deliveryId: String, + val sessionId: String, + val amount: String, + val currency: String, + val sequence: Long, + val expiresAt: Long, + val commitUrl: String? = null, + val proof: String? = null, +) { + /** Parse `amount` as base units. */ + fun amountBaseUnits(): ULong = + amount.toULongOrNull() ?: throw MppException.InvalidTransaction("invalid metering amount: $amount") +} + +@Serializable +data class MeteringUsage(val deliveryId: String, val amount: String) { + fun amountBaseUnits(): ULong = + amount.toULongOrNull() ?: throw MppException.InvalidTransaction("invalid metering usage amount: $amount") +} + +@Serializable +data class CommitReceipt( + val deliveryId: String, + val sessionId: String, + val amount: String, + val cumulative: String, + val status: CommitStatus, +) + +data class MeteredEnvelope

(val payload: P, val metering: MeteringDirective) + +/** + * Internally-tagged session action union. The discriminator lives on the + * `action` key and the payload fields are flattened alongside it. The TopUp tag + * is camelCase `topUp`. Encode/decode via [SessionActionCodec]. + */ +sealed interface SessionAction { + data class Open(val payload: OpenPayload) : SessionAction + data class Voucher(val payload: VoucherPayload) : SessionAction + data class Commit(val payload: CommitPayload) : SessionAction + data class TopUp(val payload: TopUpPayload) : SessionAction + data class Close(val payload: ClosePayload) : SessionAction +} diff --git a/kotlin/src/test/kotlin/com/solana/paykit/paycore/SessionVoucherTest.kt b/kotlin/src/test/kotlin/com/solana/paykit/paycore/SessionVoucherTest.kt new file mode 100644 index 000000000..601b4524a --- /dev/null +++ b/kotlin/src/test/kotlin/com/solana/paykit/paycore/SessionVoucherTest.kt @@ -0,0 +1,70 @@ +package com.solana.paykit.paycore + +import com.solana.paykit.protocols.mpp.client.ActiveSession +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals +import kotlin.test.assertTrue + +/** + * Byte-exact golden vectors for the payment-channel voucher preimage and the + * channel PDA. The preimage bytes are pinned against the frozen cross-SDK + * conformance vector (`harness/vectors/session-voucher.json`), since Kotlin has + * no conformance runner of its own. + */ +class SessionVoucherTest { + // channelId base58 of 32 bytes of 0x09, matching the frozen vector. + private val frozenChannel = "cGfHiC6Kgg3FpFZvgwGcswsCRtp4aBP2fzuXRQPizuN" + + @Test + fun voucherPreimageMatchesFrozenVector() { + val bytes = PaymentChannels.voucherMessageBytes(frozenChannel, 42uL, 1234L) + val expected = ByteArray(48) + for (i in 0..31) expected[i] = 9 + expected[32] = 42 // cumulative 42 LE u64 + expected[40] = 210.toByte() // 1234 = 0x04D2 LE i64 + expected[41] = 4 + assertTrue(bytes.contentEquals(expected)) + } + + @Test + fun voucherPreimageNearMaxCumulativeHasNoPrecisionLoss() { + // 18446744073709551607 = u64::MAX - 8. + val bytes = PaymentChannels.voucherMessageBytes(frozenChannel, 18446744073709551607uL, 4102444800L) + assertEquals(247, bytes[32].toInt() and 0xff) + for (i in 33..39) assertEquals(255, bytes[i].toInt() and 0xff) + // expiresAt 4102444800 = 0xF4865700 LE. + assertEquals(0, bytes[40].toInt() and 0xff) + assertEquals(87, bytes[41].toInt() and 0xff) + assertEquals(134, bytes[42].toInt() and 0xff) + assertEquals(244, bytes[43].toInt() and 0xff) + } + + @Test + fun channelPdaIsDeterministicAndSaltSensitive() { + val payer = PublicKey(ByteArray(32) { 1 }) + val payee = PublicKey(ByteArray(32) { 2 }) + val mint = PublicKey(ByteArray(32) { 3 }) + val signer = PublicKey(ByteArray(32) { 4 }) + val programId = PublicKey.fromBase58(PaymentChannels.PROGRAM_ID) + + val a = PaymentChannels.findChannelPda(payer, payee, mint, signer, 99uL, programId) + val b = PaymentChannels.findChannelPda(payer, payee, mint, signer, 99uL, programId) + val other = PaymentChannels.findChannelPda(payer, payee, mint, signer, 100uL, programId) + + assertEquals(a, b) + assertNotEquals(a, other) + } + + @Test + fun voucherSignatureVerifiesAgainstAuthorizedSigner() { + val signer = MemorySigner.fromSeed(ByteArray(32) { 42 }) + val channel = PublicKey(ByteArray(32) { 7 }).toBase58() + val session = ActiveSession(channel, signer) + + val voucher = session.signIncrement(100uL) + assertTrue(Ed25519.verify(signer.publicKeyBytes, voucher.data.messageBytes(), Base58.decode(voucher.signature))) + assertEquals(channel, voucher.data.channelId) + assertEquals("100", voucher.data.cumulative) + } +} diff --git a/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/ActiveSessionTest.kt b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/ActiveSessionTest.kt new file mode 100644 index 000000000..026813380 --- /dev/null +++ b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/ActiveSessionTest.kt @@ -0,0 +1,132 @@ +package com.solana.paykit.protocols.mpp.client + +import com.solana.paykit.paycore.MemorySigner +import com.solana.paykit.paycore.MppException +import com.solana.paykit.paycore.PublicKey +import com.solana.paykit.protocols.mpp.core.DEFAULT_SESSION_EXPIRES_AT +import com.solana.paykit.protocols.mpp.core.SessionAction +import com.solana.paykit.protocols.mpp.core.SessionMode +import com.solana.paykit.protocols.mpp.core.SignedVoucher +import com.solana.paykit.protocols.mpp.core.VoucherData +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertNull + +class ActiveSessionTest { + private fun session(seed: Byte = 42, channel: Byte = 7): ActiveSession { + val signer = MemorySigner.fromSeed(ByteArray(32) { seed }) + return ActiveSession(PublicKey(ByteArray(32) { channel }).toBase58(), signer) + } + + @Test + fun prepareDoesNotAdvanceButRecordDoes() { + val session = session() + val prepared = session.prepareIncrement(75uL) + assertEquals("75", prepared.data.cumulative) + assertEquals(1L, prepared.data.nonce) + assertEquals(0uL, session.cumulative) + + session.recordVoucher(prepared) + assertEquals(75uL, session.cumulative) + assertFailsWith { session.recordVoucher(prepared) } + } + + @Test + fun signIncrementAdvancesWatermarkAndNonce() { + val session = session() + val first = session.signIncrement(100uL) + assertEquals("100", first.data.cumulative) + assertEquals(1L, first.data.nonce) + assertEquals(100uL, session.cumulative) + + val second = session.signIncrement(10uL) + assertEquals("110", second.data.cumulative) + assertEquals(2L, second.data.nonce) + assertEquals(110uL, session.cumulative) + } + + @Test + fun signVoucherRejectsNonIncreasingAndZero() { + val session = session() + session.signIncrement(100uL) + assertFailsWith { session.signVoucher(100uL) } + assertFailsWith { session.signVoucher(50uL) } + assertFailsWith { session(seed = 9, channel = 8).signVoucher(0uL) } + } + + @Test + fun recordVoucherRejectsInvalidCumulativeAndDefaultsNonce() { + val session = session() + val bad = SignedVoucher(VoucherData(session.channelIdString(), "not-a-number", DEFAULT_SESSION_EXPIRES_AT), "sig") + assertFailsWith { session.recordVoucher(bad) } + + val noNonce = SignedVoucher(VoucherData(session.channelIdString(), "15", DEFAULT_SESSION_EXPIRES_AT, null), "sig") + session.recordVoucher(noNonce) + assertEquals(15uL, session.cumulative) + assertEquals(1uL, session.nonce) + } + + @Test + fun recordVoucherRejectsForeignChannel() { + val session = session() + val foreign = SignedVoucher(VoucherData("11111111111111111111111111111112", "10", DEFAULT_SESSION_EXPIRES_AT), "sig") + assertFailsWith { session.recordVoucher(foreign) } + assertEquals(0uL, session.cumulative) + } + + @Test + fun reconcileSettledAdvancesAndNeverRegresses() { + val session = session() + session.reconcileSettled(300uL) + assertEquals(300uL, session.cumulative) + session.reconcileSettled(100uL) + assertEquals(300uL, session.cumulative) + } + + @Test + fun expiresAtControlsVoucherExpiry() { + val session = session() + session.setExpiresAt(1234L) + assertEquals(1234L, session.prepareIncrement(10uL).data.expiresAt) + session.setExpiresAt(5678L) + assertEquals(5678L, session.prepareIncrement(10uL).data.expiresAt) + } + + @Test + fun closeActionVoucherFollowsFinalIncrement() { + val session = session() + val emptyClose = session.closeAction(null) as SessionAction.Close + assertNull(emptyClose.payload.voucher) + + session.signIncrement(100uL) + val close = session.closeAction(50uL) as SessionAction.Close + assertEquals("150", close.payload.voucher?.data?.cumulative) + + val zeroClose = session.closeAction(0uL) as SessionAction.Close + assertNull(zeroClose.payload.voucher) + } + + @Test + fun openTopupAndPullActionFields() { + val session = session() + val open = session.openAction(1_000_000uL, "txsig123") as SessionAction.Open + assertEquals(SessionMode.PUSH, open.payload.mode) + assertEquals("1000000", open.payload.deposit) + assertEquals("txsig123", open.payload.signature) + assertEquals(session.channelIdString(), open.payload.channelId) + assertEquals(session.authorizedSigner(), open.payload.authorizedSigner) + + val pull = session.openPullAction(5_000_000uL, "wallet123", "approvesig") as SessionAction.Open + assertEquals(SessionMode.PULL, pull.payload.mode) + assertEquals("5000000", pull.payload.approvedAmount) + assertEquals("wallet123", pull.payload.owner) + assertEquals(session.channelIdString(), pull.payload.tokenAccount) + assertNull(pull.payload.channelId) + + val topUp = session.topupAction(5_000_000uL, "topuptx") as SessionAction.TopUp + assertEquals("5000000", topUp.payload.newDeposit) + assertEquals("topuptx", topUp.payload.signature) + assertEquals(session.channelIdString(), topUp.payload.channelId) + } +} diff --git a/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumerTest.kt b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumerTest.kt new file mode 100644 index 000000000..7d7948519 --- /dev/null +++ b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumerTest.kt @@ -0,0 +1,153 @@ +package com.solana.paykit.protocols.mpp.client + +import com.solana.paykit.paycore.MemorySigner +import com.solana.paykit.paycore.MppException +import com.solana.paykit.paycore.PublicKey +import com.solana.paykit.protocols.mpp.core.CommitPayload +import com.solana.paykit.protocols.mpp.core.CommitReceipt +import com.solana.paykit.protocols.mpp.core.CommitStatus +import com.solana.paykit.protocols.mpp.core.DEFAULT_SESSION_EXPIRES_AT +import com.solana.paykit.protocols.mpp.core.MeteredEnvelope +import com.solana.paykit.protocols.mpp.core.MeteringDirective +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +class SessionConsumerTest { + /** Records each commit and dedupes by deliveryId (replayed on re-commit). */ + private class RecordingTransport : CommitTransport { + val commits = mutableListOf() + var fail = false + private val settled = mutableMapOf() + + override fun commit(directive: MeteringDirective, payload: CommitPayload): CommitReceipt { + if (fail) throw MppException.InvalidTransaction("commit failed") + settled[directive.deliveryId]?.let { prior -> + return CommitReceipt(directive.deliveryId, directive.sessionId, directive.amount, prior, CommitStatus.REPLAYED) + } + val cumulative = payload.voucher.data.cumulative + settled[directive.deliveryId] = cumulative + commits.add(payload) + return CommitReceipt(directive.deliveryId, directive.sessionId, directive.amount, cumulative, CommitStatus.COMMITTED) + } + } + + private class ReplayTransport(val settled: String) : CommitTransport { + override fun commit(directive: MeteringDirective, payload: CommitPayload): CommitReceipt = + CommitReceipt(directive.deliveryId, directive.sessionId, directive.amount, settled, CommitStatus.REPLAYED) + } + + private fun session(channel: Byte = 7): ActiveSession { + val signer = MemorySigner.fromSeed(ByteArray(32) { 42 }) + return ActiveSession(PublicKey(ByteArray(32) { channel }).toBase58(), signer) + } + + private fun directive(session: ActiveSession, amount: Int, deliveryId: String = "d1"): MeteringDirective = + MeteringDirective(deliveryId, session.channelIdString(), amount.toString(), "USDC", 1L, DEFAULT_SESSION_EXPIRES_AT) + + @Test + fun ackSendsCommitAndAdvancesWatermark() { + val session = session() + val transport = RecordingTransport() + val consumer = SessionConsumer(session, transport) + val delivery = consumer.accept(MeteredEnvelope("work", directive(session, 250))) + assertEquals("work", delivery.payload) + val receipt = delivery.ack() + + assertEquals("250", receipt.cumulative) + assertEquals(CommitStatus.COMMITTED, receipt.status) + assertEquals(250uL, session.cumulative) + assertEquals(1, transport.commits.size) + } + + @Test + fun commitAliasAndIntoParts() { + val session = session() + session.setExpiresAt(1234L) + val transport = RecordingTransport() + val consumer = SessionConsumer(session, transport) + + val first = consumer.accept(MeteredEnvelope("first", directive(session, 50))) + assertEquals("50", first.commit().cumulative) + assertEquals(1234L, transport.commits[0].voucher.data.expiresAt) + + val second = consumer.accept(MeteredEnvelope("second", directive(session, 75, "d2"))) + val (payload, metering) = second.intoParts() + assertEquals("second", payload) + assertEquals("75", metering.amount) + } + + @Test + fun invalidDirectivesRejectedBeforeCommit() { + val session = session() + val transport = RecordingTransport() + val consumer = SessionConsumer(session, transport) + + val wrong = MeteringDirective("d1", "other-session", "1", "USDC", 1L, DEFAULT_SESSION_EXPIRES_AT) + assertFailsWith { consumer.commitDirective(wrong) } + assertFailsWith { consumer.commitDirective(directive(session, 0)) } + val badAmount = MeteringDirective("d1", session.channelIdString(), "bad", "USDC", 1L, DEFAULT_SESSION_EXPIRES_AT) + assertFailsWith { consumer.commitDirective(badAmount) } + + assertTrue(transport.commits.isEmpty()) + assertEquals(0uL, session.cumulative) + } + + @Test + fun failedCommitDoesNotAdvanceWatermark() { + val session = session() + val transport = RecordingTransport().apply { fail = true } + val consumer = SessionConsumer(session, transport) + + assertFailsWith { consumer.commitDirective(directive(session, 250)) } + assertEquals(0uL, session.cumulative) + + transport.fail = false + assertEquals("250", consumer.commitDirective(directive(session, 250)).cumulative) + assertEquals(250uL, session.cumulative) + } + + @Test + fun duplicateDeliveryReplayDoesNotDoubleCount() { + val session = session() + val transport = RecordingTransport() + val consumer = SessionConsumer(session, transport) + val d = directive(session, 100) + + assertEquals(CommitStatus.COMMITTED, consumer.commitDirective(d).status) + assertEquals(100uL, session.cumulative) + + val r2 = consumer.commitDirective(d) + assertEquals(CommitStatus.REPLAYED, r2.status) + assertEquals("100", r2.cumulative) + assertEquals(100uL, session.cumulative) + assertEquals(1, transport.commits.size) + } + + @Test + fun replayedReceiptReconcilesToClampedSettled() { + val session = session() + val consumer = SessionConsumer(session, ReplayTransport("100")) + val receipt = consumer.commitDirective(directive(session, 250)) + assertEquals(CommitStatus.REPLAYED, receipt.status) + assertEquals(100uL, session.cumulative) + } + + @Test + fun replayedReceiptNeverRegressesWatermark() { + val session = session() + session.reconcileSettled(300uL) + val consumer = SessionConsumer(session, ReplayTransport("100")) + consumer.commitDirective(directive(session, 50)) + assertEquals(300uL, session.cumulative) + } + + @Test + fun replayedReceiptClampsInflatedServerCumulative() { + val session = session() + val consumer = SessionConsumer(session, ReplayTransport("1000000")) + consumer.commitDirective(directive(session, 250)) + assertEquals(250uL, session.cumulative) + } +} diff --git a/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionOpenerTest.kt b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionOpenerTest.kt new file mode 100644 index 000000000..fe6954c9f --- /dev/null +++ b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/client/SessionOpenerTest.kt @@ -0,0 +1,92 @@ +package com.solana.paykit.protocols.mpp.client + +import com.solana.paykit.paycore.Base58 +import com.solana.paykit.paycore.MemorySigner +import com.solana.paykit.paycore.Mints +import com.solana.paykit.paycore.MppException +import com.solana.paykit.paycore.PaymentChannels +import com.solana.paykit.paycore.PublicKey +import com.solana.paykit.protocols.mpp.core.SessionAction +import com.solana.paykit.protocols.mpp.core.SessionMode +import com.solana.paykit.protocols.mpp.core.SessionPullVoucherStrategy +import com.solana.paykit.protocols.mpp.core.SessionRequest +import com.solana.paykit.protocols.mpp.core.SessionSplit +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertNotNull + +class SessionOpenerTest { + private val operatorAddress = Base58.encode(ByteArray(32) { 5 }) + private val recipient = Base58.encode(ByteArray(32) { 6 }) + private val blockhash = Base58.encode(ByteArray(32) { 0x11 }) + + private fun request( + modes: List = listOf(SessionMode.PULL), + strategy: SessionPullVoucherStrategy? = SessionPullVoucherStrategy.CLIENT_VOUCHER, + splits: List = emptyList(), + ) = SessionRequest( + cap = "1000000", currency = "USDC", decimals = 6, network = "localnet", + operator = operatorAddress, recipient = recipient, splits = splits, modes = modes, pullVoucherStrategy = strategy, + ) + + private fun payerSigner() = MemorySigner.fromSeed(ByteArray(32) { 1 }) + private fun sessionSigner() = MemorySigner.fromSeed(ByteArray(32) { 2 }) + + @Test + fun buildsPullClientVoucherOpenAction() { + val sessionSigner = sessionSigner() + val payer = payerSigner() + val opener = PaymentChannelSession.open(request(), payer, sessionSigner, blockhash) + + assertEquals(opener.open.channelId.toBase58(), opener.session.channelIdString()) + val open = opener.action as SessionAction.Open + assertEquals(SessionMode.PULL, open.payload.mode) + assertEquals(opener.open.channelId.toBase58(), open.payload.channelId) + assertEquals(PublicKey(payer.publicKeyBytes).toBase58(), open.payload.payer) + assertEquals(sessionSigner.address, open.payload.authorizedSigner) + assertEquals(PENDING_SERVER_SIGNATURE, open.payload.signature) + assertNotNull(open.payload.transaction) + // localnet USDC resolves to the mainnet mint on the MPP charge path. + assertEquals(Mints.USDC_MAINNET, opener.open.mint.toBase58()) + assertEquals(1_000_000uL, opener.open.deposit) + assertEquals(PaymentChannels.DEFAULT_GRACE_PERIOD_SECONDS, opener.open.gracePeriod) + } + + @Test + fun appliesSessionOptions() { + val opener = PaymentChannelSession.open( + request(), payerSigner(), sessionSigner(), blockhash, + PaymentChannelSessionOpenOptions(cumulative = 20uL, expiresAt = 1234L), + ) + val voucher = opener.session.prepareIncrement(5uL) + assertEquals("25", voucher.data.cumulative) + assertEquals(1234L, voucher.data.expiresAt) + } + + @Test + fun rejectsNonPullChallenge() { + assertFailsWith { + PaymentChannelSession.open(request(modes = listOf(SessionMode.PUSH), strategy = null), payerSigner(), sessionSigner(), blockhash) + } + } + + @Test + fun rejectsOperatedVoucherChallenge() { + assertFailsWith { + PaymentChannelSession.open(request(strategy = SessionPullVoucherStrategy.OPERATED_VOUCHER), payerSigner(), sessionSigner(), blockhash) + } + } + + @Test + fun rejectsInvalidSessionSplitBpsAsMppException() { + assertFailsWith { + PaymentChannelSession.open( + request(splits = listOf(SessionSplit(recipient = recipient, bps = 0x1_0000))), + payerSigner(), + sessionSigner(), + blockhash, + ) + } + } +} diff --git a/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/core/SessionWireTest.kt b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/core/SessionWireTest.kt new file mode 100644 index 000000000..7c237a155 --- /dev/null +++ b/kotlin/src/test/kotlin/com/solana/paykit/protocols/mpp/core/SessionWireTest.kt @@ -0,0 +1,78 @@ +package com.solana.paykit.protocols.mpp.core + +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonPrimitive +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class SessionWireTest { + private val json = Json { ignoreUnknownKeys = true } + + @Test + fun openActionFlattensTagAndSerializesSaltAsString() { + val action = SessionAction.Open( + OpenPayload.paymentChannel( + SessionMode.PULL, "Chan", "1000", "Payer", "Payee", "Mint", 42uL, 900u, "Auth", "Sig" + ) + ) + val obj = SessionActionCodec.toJsonObject(action) + assertEquals("open", obj["action"]?.jsonPrimitive?.content) + assertEquals("pull", obj["mode"]?.jsonPrimitive?.content) + assertEquals("Chan", obj["channelId"]?.jsonPrimitive?.content) + // salt is a decimal string, not a number. + val salt = obj["salt"]?.jsonPrimitive + assertEquals("42", salt?.content) + assertTrue(salt?.isString == true) + assertEquals("Auth", obj["authorizedSigner"]?.jsonPrimitive?.content) + } + + @Test + fun topUpActionUsesCamelCaseTag() { + val obj = SessionActionCodec.toJsonObject(SessionAction.TopUp(TopUpPayload("Chan", "500", "Sig"))) + assertEquals("topUp", obj["action"]?.jsonPrimitive?.content) + assertEquals("500", obj["newDeposit"]?.jsonPrimitive?.content) + } + + @Test + fun sessionActionRoundTrips() { + val voucher = SignedVoucher(VoucherData("Chan", "250", 4_102_444_800L, 3L), "Sig") + val actions = listOf( + SessionAction.Open(OpenPayload.push("Chan", "1000", "Auth", "Sig")), + SessionAction.Voucher(VoucherPayload(voucher)), + SessionAction.Commit(CommitPayload("d1", voucher)), + SessionAction.TopUp(TopUpPayload("Chan", "500", "Sig")), + SessionAction.Close(ClosePayload("Chan", voucher)), + ) + for (action in actions) { + assertEquals(action, SessionActionCodec.decodeFromString(SessionActionCodec.encodeToString(action))) + } + } + + @Test + fun voucherDataEncodesCumulativeAmountAndReadsAlias() { + val encoded = json.encodeToString(VoucherData.serializer(), VoucherData("Chan", "250", 100L)) + val tree = json.parseToJsonElement(encoded) + assertEquals("250", (tree as kotlinx.serialization.json.JsonObject)["cumulativeAmount"]?.jsonPrimitive?.content) + assertNull(tree["cumulative"]) + + val canonical = json.decodeFromString(VoucherData.serializer(), """{"channelId":"Chan","cumulativeAmount":"7","expiresAt":1}""") + assertEquals("7", canonical.cumulative) + val alias = json.decodeFromString(VoucherData.serializer(), """{"channelId":"Chan","cumulative":"9","expiresAt":1}""") + assertEquals("9", alias.cumulative) + } + + @Test + fun openPayloadReadsSaltFromStringOrNumber() { + val fromString = json.decodeFromString( + OpenPayload.serializer(), """{"mode":"pull","salt":"42","authorizedSigner":"A","signature":"S"}""" + ) + assertEquals(42uL, fromString.salt) + val fromNumber = json.decodeFromString( + OpenPayload.serializer(), """{"mode":"pull","salt":42,"authorizedSigner":"A","signature":"S"}""" + ) + assertEquals(42uL, fromNumber.salt) + } +} diff --git a/rust/crates/mpp/tests/charge_integration.rs b/rust/crates/mpp/tests/charge_integration.rs index 6ed6e381d..584c195e4 100644 --- a/rust/crates/mpp/tests/charge_integration.rs +++ b/rust/crates/mpp/tests/charge_integration.rs @@ -17,8 +17,13 @@ use tokio::time::{sleep, Duration}; const SURFPOOL_DATASOURCE_RPC_URL_ENV: &str = "SURFPOOL_DATASOURCE_RPC_URL"; async fn start_surfnet() -> Option { - let datasource_rpc_url = std::env::var(SURFPOOL_DATASOURCE_RPC_URL_ENV) - .unwrap_or_else(|_| "https://api.mainnet-beta.solana.com".to_string()); + let datasource_rpc_url = match std::env::var(SURFPOOL_DATASOURCE_RPC_URL_ENV) { + Ok(value) if !value.trim().is_empty() => value, + _ => { + eprintln!("skipping surfpool test: {SURFPOOL_DATASOURCE_RPC_URL_ENV} is not set"); + return None; + } + }; match Surfnet::builder() .remote_rpc_url(datasource_rpc_url) diff --git a/typescript/packages/mpp/src/__tests__/client-charge-integration.test.ts b/typescript/packages/mpp/src/__tests__/client-charge-integration.test.ts index 7a7713681..1170743f7 100644 --- a/typescript/packages/mpp/src/__tests__/client-charge-integration.test.ts +++ b/typescript/packages/mpp/src/__tests__/client-charge-integration.test.ts @@ -23,6 +23,7 @@ import { TOKEN_PROGRAM } from '../constants.js'; // SURFPOOL_DATASOURCE_RPC_URL secret (see .github/workflows/ci.yml); without it // surfnet clones from the public mainnet-beta RPC, which rate-limits and crashes // the embedded validator mid-test. Mirrors the Rust harness's start_surfnet(). +const HAS_DATASOURCE_RPC = Boolean(process.env.SURFPOOL_DATASOURCE_RPC_URL?.trim()); const DATASOURCE_RPC_URL = process.env.SURFPOOL_DATASOURCE_RPC_URL ?? 'https://api.mainnet-beta.solana.com'; // ── Helpers ── @@ -304,37 +305,40 @@ describe('client charge integration (surfpool)', () => { expect(decoded.payload.transaction).toBeDefined(); }); - test('SPL token transfer — resolves tokenProgram from RPC when not specified', async () => { - // Start a surfnet with mainnet RPC fallback so the USDC mint account - // can be cloned and its owner (TOKEN_PROGRAM) resolved on-chain. - const remoteSurfnet = Surfnet.startWithConfig({ - remoteRpcUrl: DATASOURCE_RPC_URL, - }); - const remoteSigner = await createKeyPairSignerFromBytes(new Uint8Array(remoteSurfnet.payerSecretKey)); - remoteSurfnet.fundSol(remoteSigner.address, 10_000_000_000); - - // Use the real mainnet USDC mint address. - const USDC_MAINNET = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; - const remoteRecipient = Surfnet.newKeypair().publicKey; - remoteSurfnet.fundToken(remoteSigner.address, USDC_MAINNET, 10_000_000); - - const method = charge({ signer: remoteSigner, rpcUrl: remoteSurfnet.rpcUrl }); - - const challenge = makeChallenge({ - amount: '500000', - currency: USDC_MAINNET, - decimals: 6, - recipient: remoteRecipient, - // No tokenProgram — should resolve from on-chain mint account via RPC fallback. - }); - - // Remove tokenProgram from methodDetails so resolveTokenProgram is invoked. - delete (challenge.request.methodDetails as any).tokenProgram; - - const credential = await method.createCredential({ challenge }); - const decoded = decodeCredential(credential); - expect(decoded.payload.type).toBe('transaction'); - }); + test.runIf(HAS_DATASOURCE_RPC)( + 'SPL token transfer — resolves tokenProgram from RPC when not specified', + async () => { + // Start a surfnet with mainnet RPC fallback so the USDC mint account + // can be cloned and its owner (TOKEN_PROGRAM) resolved on-chain. + const remoteSurfnet = Surfnet.startWithConfig({ + remoteRpcUrl: DATASOURCE_RPC_URL, + }); + const remoteSigner = await createKeyPairSignerFromBytes(new Uint8Array(remoteSurfnet.payerSecretKey)); + remoteSurfnet.fundSol(remoteSigner.address, 10_000_000_000); + + // Use the real mainnet USDC mint address. + const USDC_MAINNET = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; + const remoteRecipient = Surfnet.newKeypair().publicKey; + remoteSurfnet.fundToken(remoteSigner.address, USDC_MAINNET, 10_000_000); + + const method = charge({ signer: remoteSigner, rpcUrl: remoteSurfnet.rpcUrl }); + + const challenge = makeChallenge({ + amount: '500000', + currency: USDC_MAINNET, + decimals: 6, + recipient: remoteRecipient, + // No tokenProgram — should resolve from on-chain mint account via RPC fallback. + }); + + // Remove tokenProgram from methodDetails so resolveTokenProgram is invoked. + delete (challenge.request.methodDetails as any).tokenProgram; + + const credential = await method.createCredential({ challenge }); + const decoded = decodeCredential(credential); + expect(decoded.payload.type).toBe('transaction'); + }, + ); test('SPL token transfer with splits', async () => { const splitRecipient = Surfnet.newKeypair().publicKey;

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 diff --git a/kotlin/examples/AndroidDemo/docs/e2e-1-launch.png b/kotlin/examples/AndroidDemo/docs/e2e-1-launch.png deleted file mode 100644 index 5d0e6400d56f955fb06ed28bbb3e01e55d696a15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29005 zcmc$`WmwfwxG%T~L6J}?X%Oj>ZV*s9rCYkY8&N>IJC*M4?gr`Z?(Vv4pPBn%=A1jv zGta#<*Dus&v)1~rH-7ONAS*3`f`p3%fk05iM8AB4Kwv&YAh6yq5x{p2!~gsQA7Jdh zi3mc9hw*p87w~q1VhS(8KlhjVzabD}h}aha1?S|0MJELeWxUo^qNdj`so&{+Emg)i zAS=7}X)+582nZI znjMdb;Zf81@ZeE{)6wA3WCD|cIF}FcOEuA&Ot?4j0+duAV32&$tG>WuzzdiKz*D~T znHpo*g#<>5VX3IA>*?sgd^R_yjfjZo?Cy??ja6!YizIkjUQ?6fcsMsRKd)zQ zE-5Go+t${0b9eU+A76v=5L=kLD@ztVJu8chii)aNzno_vF(Dx$Hr7vro?-CKM{;s< zg<=gHL_|dKIQo#fI!=gufjwO;5+Ux@```QIL_naC38$l$5M>I!+b!X?Gjw?ELkXR9Lo1t%_$rOrMv^Kh&-&{^>mz9>L8;zuj&+knZV1q|Yt5*3NlSb*giHX?t(ctQvP_fy8Ei zOrBx^R(5vw&d$zvW8>dtWsKe3-S2U6|7K+T1m{>~Hk~aVL%p*X_(yj2k;QgHv?@|t zX)<3?Z=*NDG;T!FlZ1pM(NB48!gYJO&dxv0>nY)Udt_T>dt>8QXecToD*k8sxbuTq z=A)%1n#&W2hNfno>>t=HiMVV*UnGrM>mNHi#_jFxwVsb$sHmu>77_&DnkW<~p(IFl zPZlV<+@6t%iHT)qW`;*b`e@KoeEj&UK)EC`JpA+J-elIPfPnMz#@^!cbq|7c!|l5%hMKmzSfHlVltm@f#cZ)Qb7Ps;a8m z$!duk8QeWQIGs<3d0j7L8;09{BA#Ae4pnGOZEPPNO8KJ_AiXmUpuA{k1sj{lR}4zw zb`l@JV$hP*)%^e#4@XQ!_Ejw|IT_hIB0}zuIe!H^HUWVY2o3OrNO^eh>oh`}oB5QK zlt9#wM)iGSV^hi{eR-S#4p`61N@l$~%%@``ekDGUnb&TuKVT zPXv^;t)ZladIt%$)cAOn_#`>?FJIt6R3ZJW0~Z4R#f!ICSV|ulUkQp?J2{Qm1=D~0 z2=C-{%`@LG>1i~a?2;2jgrN&tSy`!nbFvDLh*;rttd(W3w!RMYiG?LP*5Ik7G*aK( zybvQSAt6C<Lt$iOY#SMoxq!SVdW(-g_yZ0RBbI=} zns~&@sxhn&4QZ8J6q+~e?cu-oM^ho~hvIX#ComgjHna)|2pr7Ugn@g)>~>|o8+!6b z$R7#U?<3fVw>Jc2gIo}cLrLru;HH77uy=4MtE|j4pDllnhiCWvjg9S}mPYjB$B#92VxK8nN5^62+sP8`G|$I7D$Q$% z40s1?RLefLMt<-_7I^b(p>eteAu2Xj*xtU}p$bbFPcdumMz!#CdO9ypC;^Sw5HDX7l;P=8wN=38fHgBJQ zJi`r5t;Rg-WQ$5v)8Xd+{=5aHrR=%Y6B>t`sFV2b8O=F_5Ky{XTR&&8Rr%)I>FMi# zDN3xm$<=hbyV#TRMZy#(=34cTH|K4Y1Q*>IpTE15L5@^n(v5w`vxq6_%Ryuy1fMyHXmQYIp6Ts`fo~rh<=g`0Q(U zFp*w-J9zcx`~H;$G9kyyCXGmOTU#de8Y{(ursJHUbfqCRq=B)qF%G9y9{FsU%`^-3 zyd&8ZIZ|OP)5U`aIM~b$cB?B5KQz4Ja1ILhQ?fL#+ZPnlDI3@PY$ua(=o54N77iCH zI=*)33}M@y0qBFzHZT?2Lu6E(2{su$vEP5SHx$oU`LGl&d%Im9uX?Pz7H`sPHFu7; zem0%{=8>0(r>UtqS8dsmoKOLCa~QTP2KtM!`j*1`7occS=<(}Z^vZF%hB$5>#BK42 z2ppVTXD6eiM+;3716Xvn(PCm!o4uo?_?H~wD-}l3RPugT7W0h%EFhrBbM}jfh*az^ zFKW~}N5nB`>*~qlZVL}z?9a!c(YWWzUbS`jAI#MKq>d^0S0thQG;>3trKMF{U(e*x z&yuI1qVj%z(aE}RpUKvRhc(%BtVV_?8J|G4$q@zY`{rSM#J1C8tm@Rl9R_ zuN$5hJ7&*~UcGv?3Fqd<<#6yNZOP-`^!U2VKf48|!;QomcBTYmf78jG$qb6axoUY_ zGjUUD3YpZEnSgbkQ!k%@0IJLV$qePN)Y~U(Y$Ta7iq`6)`R^76L*No8u$-#*$I>Nb zNXp7~JFB{IbE{Pw=VfAE8c4n0yMmm{UoSPeeHKPzcN^;y7ZLIIeU0_*ElwLEk$bqF zhomI(vgDoLPk%HW<>Aoi2@Ln+TidMzoW>Hj3d2oPUmJ!J8ZGzp#hPEg{B%LN?n0x1 zKAU0f+SX$)%at@Kb>oTB2!*H1eP#27#sI%dyi&6fOYrF6TK$Qhuq&4J`2E6g1w@UF zyX%pNY0kLCY3M0~l`^_*(fV>t*$r1cFOGPnYb&2hv)n zXF?Dwo!hZ!iw%zJQKxBd@$e+T$p{Jx)!AL6f`HI#TeuCz=MyC921SZo>NYegH3yQb zSb_ESEyGFuT9*}`r&0IBuKQJAjxK%$Jmx)FDY)xGh-f6B?G0Ne6d%xEdU(%fA3w)V zq;TqXK=IgOo{-#EUAl+Ry`el0Syj2)HE}8m3m`FaLNkx zGW-vfZ^HBlFOKKYN?ylt)?P!D88mgk0elhu%4Bedv9{Sy#M_SsE+EL)ADE~k)6>%h z12(&d@Z42ag^JxY*ORw#+=~~#5A{z%9x5zoe)^&OQI9Kj)@}}*_8qvnTZr%zi=|c1 z|CAY#nmT-NYsb0k5-3f;WqbQT7D~u7csp)nvs_OA&;k~n=3q12{p-W{mx(l2@bSr! zlGm1tKZ27;W|xyei)_BwjN*Ny*$|Z+8F_5+_3PI%`&%Z+!rf)h*jRb*UcWvQgqD`} z4Cl~`?Wrun)nOm@IYb229uGo%IRklkAe3t`q~pV34)yf76DPv*^Ye3m+BKSqrVjxT znab;yZO^U#H1{QLSTpxX7P=k?z4qxE*yv15h2ClVSMVWf4u6L&JX? z`Ncn6{Daz`P41U-b}m{Uzre?L9Gsj9iL9povK7sSQ~CXCu30rSHL@<_=(Rtbs1h&M z+h^HkiSwMfMH?l7?2Q?hO+U5_0Oqe>zpO#Lfh(V8JT z9GjL>-8W$?MkXe4wXMCieCva9CKi^=HGfPOg0~>mM~^Wjh%poZoC5pFd4+gzaL~5! z*?u8MqscL3W8>Kmo@c}v_S3&16nXSxZQ)`S%LPfMnJV;dno6ql^z_n)Z0At;xib))#1fnJgqKPw zN~>yxMWtt+`Lw?}Szrw@H#b*^?K}7p)bmGN8dRLYrQZp8RGF3Jhn|kXJ!;X#LZ+5Phv{p}RD%+Y2Jz1QX;9SVs!SDq9s23x z6i%tk#3Us2x<&?e7s{gA4a|<8JnDAsr)}6eT8| z4q0zM_epHoR997H>Be%;ya?!;o6G;V#>_l$^LY>-PlRTvP21+w6U@iEi=i^U{UI0!1M;Yq@HbieQA@~T6NResYFDfNM7HZ&D4_UC zEOI%pE*W|r@LNN?wRl~{46gP0}>^6kJ2QW0OQ?)`0)+>%F7B@%cSs2uQwA1lO) z$mM>)=o$8?Qfo{y@-ub3#wktE!??N@+TjSmA;6YyrqNLkXrBKE*jHDdhiwt)XzzfO zGNhdw3V-|d?&;|Xw`R6hP7iWLFq2bx?Xjlcz2Z4_Y{>3pfzaxBO(0HG_oKb(fp>Ga zFSf`Fw9K8QZGp>F3`Z&oCZjxhFMB-V8phUlj*myEWMnQbFHIIGuO+Ph>_p!j!=O5! zJBw^(Fg)I0(ezm(Z48`h1KOo84exoaL<&!A=n4VZ`7XNd^%l%0orgG1&m{@@1Sh}i zqj?DcrYm{K$^B-}w?w@Pm_rluEcV$zVqFJq4!2`HO`#j%g@%dk@mL=7)zy`=_O;>U zo?@oHoBeL)HWlCA#E*jM;yeO>CWa2J@~7+N_va?v*Ir)n?EE5V^|iWv68>TQ-F>4G zW=l)vx7${}A1R~yR2t2xAkYM>F>Cu3Hz-{#KnoVG(sC9FWO$#SKW%L7JHK}65ghvj z5-I6FGVH&Xxq=nKAf)x%_`#Y{!;P<&sPWkJ%xM)xs1ns@YX{~tP}u18;zs^ zG)`-A>|b{dI&9^#uD?|B=V{`Mte{DiHF1Jj6sDx@OR-Vz7TSJL<8?8EQ4|PA9?yqf*pLk6)nWqhr zaaiIB7wfV6r_%ua0B{|1P#pd0?;bf5i3ub^wwoqC@0gt`2Fp$JHxW*FbDEspOQ|ntg3g&6ZGb0%Bo(fcf}j+9^sN z{QRw`C!oB+{`MWHpb8HsLR=0zqM*IsnaWZxc2W+a#*&)M)AZ*(YPfZHq1rH&&^I|AFH#dUNHZN($m}c@uouLYD5%MhN4>=&3r_=)>;L;JBDcq2GkZ7bRLHV>4MsRx|W8a zb#*SGMCP^DjO#S|tSJg!+q2+MsIA0Cwk!g=78V*?^_m4&X-<=f+vmx&2uE&SX)}4Y zVT?M%}=Ka|GBB&fl57_7LAB^ z4IqW!;9!*s-56oLK%bLpz&6PCgB%8c*9xd;H;6a#t3Qz{%|~HtJRbp&Y|89F|0PKB zf3Ok3|B221-$YiJic3qAld-Z+GXX3F$S7?2FIF|6rs8whmu7ZQvbi*|Eg867JxR#Q z%8L2ReGDXn@dOpUw$j*7BFM0|+FW>~xk;tj^hJbRL|2(hmBr0I8a1Z^2?vLY+ST2q zS@VM{Y=~x(Y>AwQr^*c}AOess9|-RmZ3iiFSxmkhA~+hqlY1gOBsxL|j4Q@}U#1B)>zsFW1I!z8i!_=7TaA8@5eP?6#=^g+h&t`sUgvCl zCicG~(7zosXmmdHDQQU%RZ~;5`4yf6%7f>F35mC$)z4I*-NTC=j$1prpcD14iwLw>Avm2)abpxPI*x8v;AK z*LnD@2^B`xw)p}8^kmJ;PsTEVB1fxLAJ55bRPlWkZR`xJh1=dAhV;ci7J;+Adf=RTe!>G! z5Zuup%z!O4n{I+Jo-D`ADk{oy0L9IDxi&Q74++SPIg$xXb=7g|>NS?j zTWuZpAaN#KT-e9-aP!~CM<(_su=fnLw|^kL@`n8V`@v+QRIXWXI9mBWp(F~A-RcCS z$wJy94(BRZ_xGq*krqIym9NyX~lP&V`!TsJ%o%#)e>Qu8;iL*7h9)?`fgcX*~N40m0BE z-t_KRMH0)=irX{cYizpcJwCUmV355tGBO$u7v{coug4<-N|>+do{|;~4GpL$zGse` zSq7W^vo_mD1d)+UYnC(VB;ay<(SB|jiHu_q%2TY!9cD=EY7uD!`iR68bP5;j;91nCA=PV~w9*7s~<E92;hVw)I0LU#gLcUgue-N!kXPDO0D2n%th8RG0*f`?V=DObL2OYU0 z^z84ij`c2TM|seY)&SiUjLR;(c{)782WUkmuq>pwS^!9N$76@;2!Af<4pWz0!FXyl z2Y;2oMn}gR_#uRd!(#rMWrES}iWY>V*gc#5hV`%}M^A;($S!|xNX7ODmAMs2i8$wd z@xkj3XCH~2?&68CA9F99^X^@h9RB0ro58_%O~DO{V-bz;&)0kd9W#DDXEbATH86u&&fEI%Q zoi2fFz$;s7pKa`}+2ih$#hC(e1_hVd5iJ&j#uvaF!sKd~@GXxdbdAFKjtSTa&kRi8bM&BcN9ces<@v!yeQd3Y=uIaYSg%u0-)Ne~8+Y zh}$$~D5=JxSM5xUF*Bb1ptlHR8*L9wi+estc?<@X>xHWiMp1ag86~Nbk&&Iw6Sdem zKa-epa7H91_8+*|Id5FQ-0mLc>~E;A{RCJq$i>AahsPF+g<2H?lh$*PmsWc|W`Xfy zIc7LxXfm&uVRu2_J`P5hnO4v0e895t!qa``jH`E4w!273eO0bp4Hlqow}2{RuJX(c zD7c;7T}Fp9jL67$ryN^tfRL*5*hVe0DT9D;A3t43O>S|9@s7%o9tGW0)_h+<(ScI2 zR$siFUS^c`8<2}7lUX7Hw52iuIEFke++Z(Dr*_svQBW;lIyl(GJS{hCx&aI&^X1F0 z%0hX6>9Oa>$H#!s&_9<+>~B7UlLjYCva%~5bIRj<6W$|3NGc<`GC0ee%;|;z!~)C3 zX5W@)^mpj*tSuK*sQE!NVkntXY@`0;hfF|7NLIqW*FB5zN;*%Nvd)2?rEQR^Jd`z< zcp~*wy?(t-pG-kdADZT=lFM=nbFnj}dFSPeMooD^%N(X0WH^*%@OXczJQtc>VkFB` z9DZ-pD|3GwrMnL^oWvW~Y(>u~B`JyFDg({EPcE;TuibY?i@24Prp7oVvk4d7O3kk6 zxg2+T0k%~sHx3v(%pF(C2C-|svGX>TL9@F{0z2UMVC^q1yCYgU^~%nP31shR+OTT< zC79u*dkJuj&Mxv;>@2!L&ziM)I9HivlM(z;o_wG-P&#(s$*v;!u(MBJMNJL%I}qfG z!U6)?rlznKX?YbqczOF{sU++rE5|(Geuu@uSP$JNw%Yi;gQ0)$-Xad%1-|HEL=on8$ z-2i#ekiZSbcs!p~-bhl<{~op8=`h=#SbedY>FZaAG5w4G?gbDTtq_sf9V4ZsMfQF~ zyaufgnze&X7wEkJc}8^=r^5hReg#o)K$k(={Hx7@^C4w)%t&#d`C?Wlgoi`YPbi0i z*uxe9))F>J-W-@m2LNDZMrF4P=Pi!dO2y}cfjDI~#Ma_u0?@BYzJE3d#ja{;;RhL& zG$^cRa6)138JnaHu&886%%2IGyc4oGy1C#-e zfopT=OxDyo1P}oI<^Tt9b?HXegg|0vcD|7foi36XIpSrRn`ScTe*@kNFzpxhu2&kj zr(+wJh2oYyBpe?zTMt_XmI4v~TwXA>*8-ZMudfeE#z@35M8w`LuT#dx#$N1BCXo%q zj%C@!!B)lOiPRhoCh;oY)$H`7K~!$fk>;vRf`B~!=z481A8G*vY5ibL%X#sV)TT_f zvGH-$DpyQsNIqS0M@B}1JVguu&x8hHsAid|uYzMo8s2*z>+tB`&K5D!&6g3dl=EKj+RAY zs1=Qu3OT)=&)LB<>KtJ1&KgeTEvRf-n9Elv`v87tH7vvnDqKmD>y3_e#W(HF=989q zumFO}v&q$2^Awh;I}fNNxw{HNrb1Ei6$1qx36jD@HO*tLKo5&srk2cnlKC|MCf%pn@d0l%Gx8adB1nLr}m z+M**eWzUtcx9=v)049?l&xZiz67A96t^}pSxf4K*)Ur50yC^b#y0yEIeHPQXc(9f- z8lxU4_cW)aWkIKLLK@dZKb|f|T7P}irmQWUZW@y>eofJGfAe^8tXlKr#bRyQ3CMe# z9X8q3qXu$DnkZ1zudW`B;~XSY7*h<3)K}*6Il47Fi`HkrIbo$bm$fnu$O{;+c|*?O(0Y8Fg9 zyda>>_A@d$kbV5PqL4%0gX$)`*!E*5{(WIlAqIVt9XdMtPXNQl9>vAPNa*QNX=rG& zPWShAsSXWR5{C3Y9u+=DyR z+4+CWCWqIf`%h0Lcn|gYDPRrDcM8u-8I@?LdRN75?m}r z-#(1MnC`7*Nzkg)dNXEpH;(tAG0}?v?ymT(I4zxk-2Ij;sm6Tuxaj%2j^%J?2|0Bz z-RrLPlpO%Xh%tO?*2sSozZ4XE^FNS`i=3EX3{x`FYqw~e)wkS5UCx<>O8{S7C7E4g zz~>*yVU%w??@s1pdaMsS$R+Zl{u~p-zWMjV@U3j$AEX%keBz)m<@)AlVsY(!OxW*>6@@)-f0 zU%@ul=Q>H7XIM&ZQ2ATrdBn@xYiaV<2g)7yx3?+he{PeO-MQV4%tIXji&eXoa_UDn zn8Wy*i{CdY108??VE4#0&{Ae@o<7*#rl4y8eSyRNL|1Do@pIdjV3ggK&D#6V0hb3$ zU7QNPbVa?dkCxY;ej<)7GiWt_AK-s}RI>#p6AE4#F@E$HIOph4nGgV8*&9_W2dI_f zc?IT*h==&GS$oUen3&-6+av?om-?dA@@643zz%))_#w6CA+AQZRC01+jf&6J3mUr#J|)3b>NEJ8 zn?7`MHxT%1Zs>W8xZ;CudAShv>t)Q4qO#&bknU|2PK zpS@Vm*toankpHho!YndwCrlVx6UIr*qr=j8v`F2T8BeY5_l{EFFKMa zczK~x1iOdj*kBb7UybExmb{U@z5N;Mvp{y^mX|D>k+4z`s26+J+>2EMhd zo>W4aHp3#R8mT3>u&>6JVJ_7>SbHBJirAZ0rDd_eqB918&_t2 zVb5W8ff3bgA%8UH^cFneXaGH5N=OpB7!hsx&5g!3jU2n9qFwFI-kvEBQD0|CGlK2# zA_+#zhhvzzI0hNO*Z}v`CV(5jLBZs)$1>csD+W*p?NFFp`0Xnsu4f?tJzcL4hJ4x2 zLzB5Y68V~JJvn*#8Og~g#w*;=st;$#LkjAS?Tt=a1wI-y{764qcu&Chq;lsqutjG( zNEMlq-IHUP!UekOAJG#E!zuhCfXf3k+rMH9ZgRHe4bu9z-~ zxRWlU_0xJ+-x7i4EH>vdAKc{b=^@cC?imo(oni6lI90^3I*;I(nt zjDK$@j01kc7Eo0Co~k0>)7O6S?+u4UI1C32YLkUV^(hQ*=kK1{6ds9!5U;UXUW=SI z*u}51oDHOzE)Gvl4we|tzU3po4G>EJ;TX}U|4_BtvOF3T9H`&kS;FDDp^^&SLqk5N z29j;#>$~|#!8S|@SbLMX=rm>8p7wU10QBa+l~t@&W|O)g4l7M2)$VpLdpgh#&H@>Rwn7tdAZzcA*KjtG;gK zQ)96rc~s-jU(la{r)a-3Xhw$3bvC5=vh(C955b`Jm-d5Rf^ zKSIR>MrKJ{M4+~t{lqHwg(uS8)fqYgOUN4Vdz?2hE~6Y--<%O4g2PztVPMy z6$wE>L1AQO&XDU69?Q}^Hynas5N1&JKES&SJ*S%wBO7ovyU>!Eg?%XS>HI%wY2(?y zzARSOj(dY4FrRuYh@m|a+_o^3M$224>T{S+91epKb#hK(yFJF=-PsXEe_?QCe&!~L z%N?jP;8M*3`Wv?*P!HqriK*?Yn& zo)d0>lw#A98@jO7?Hw%9l)GabvV{S2x!vXVzbMXIPbn4|4MJwRF$YoN7 z54oLe3nj$Gb?*jM7cMX9Di2>YIk)vP>b)-Fb?EBsJUL$SKpN0LJvDb)ex;A^e|W?_ zd(<37aKz2&eDetuccgvr!!E)a;>Llc0C?x;HaO4a6QfWEE#+eC?O{zqe$Q{P5hh35 zn>4^p(LCnBSXOqh(4?-Dz@s(HuU-R#)3cgZH2;a6y<>P7RW&(SOg`J@u^YuCg-1(k zSqhCla)3h(}^1^+r17Ep4@MBwxNGPou{Cs#iyVU>7Sn^i5qY^IUz9^ zh$aIl9#~hTU0u1FuaDm1-bL`%?s8QeWO0=2`4@+9!VPSO>;jx!HJ;M-_-VVjH z;+4=S{|*e)-Ab+-%evkF{nBtawV;v^h_A8`EqFw9iYUx}Mll(gp4Qe<*|~S{78k=8 z5a7<5IXaRyH^;}q+DhiIiL}&gc!PySAM@&^bN}T&`^}+O%in^6pcG9`$K%^L8@(RL z$-2)ia6O;(j-WkzLp(JrZ~+wBn=I=1@zdXU?SQt5)#1zu`hrz|Ob+LrmmY4{A4nJ@ zic`49tEJ5H7JOf0=PB1%7GFYK?e_us5QoFkiqf+;dG3KfoXRZ%L~Br$b&i`K2h+H@ zmn~lTRMP-f93MY;d$)qe^X%8g#)ifK{ew>P*d_u3LZ#(oAmH9cSJ%T%cs%^Hy;M7< zEatPAU}VzX0aC5;1wU+fczkQYi82IGNIJ&xqv}Y=?!qV(6uV~=Wv&k7GIvTkZV3ib zQj!5)c6M!p!1X%tjaIEZy0(@BWfW{70y8= zP^mZP1bPgM>BJiv2?<~JmLET0LMIE(H?h+s1^}oOla%b7n-fV0Gb!kNMsvw zIvY^P5;qte8oFH{Y1vuGlMlUQHRX7V|4vZc776HBU7xjyyq>-BH%%uC`=ruLb89e8Hjy1V^Ao|`Iq4*AvjrD}b8d{TZE4#?`zADnM9hyp;6+FfTu znzfl!R}aYfo>{x?$)#rE#=~G_6dO=q=~KAZT<**xtV(*_yu;FX+J=g>|5QyEnPEE~ zElCw6vf38X=$Q?$YfF87;y2jsoFHGdm z792s_l&hA7l+okq0}dRBh(NiKBTXO51hJrpmkf)G$} zttZxR-m1s-!Vly*TuU(d7Mc<5PrX2;@zEZKm#H;{jMxV=fHZM>m@ZX zS4VE0_F8a$2Hez0Du0IbA(!}kbe}$uR-}!MUmBPX{A*M_$3OSMFl_qWD_X48B&e@| zQC(dP`lGh?_P?V0nssYm73^8Syhl$}o%WTAGc`?ItE$__UsLb061U_KHC}?lQ>yO2Z1xA%phx=-LG5Y&6(7+bE zxG^95-_}-}hTadSh|jwL^8OK_u54pFYr*Tp+ki&-)A!!bfOE7BA#J&|Txb*k-S2Gq zB@y8*ukLK1!NtLJ5)h*?#hQ|8+;=95n4vguc##{*`vIF;#FpWxzBbF^HrSnTD8bN} z0sr=$TCe93pts^#Ho51jOa>fE%#iVTSf)J`l;xV~UtBh6zdA92FmDfjpfZD1C@(BM zm~HTHZo1#7a|ccZ$@m-0EyFFKZn2BpN`fZ1dvGFHbAB;_-HpCs(J2xb;E22)6U^{$ z^WuP;AbNLv2UtMW*`J3NRPAQ!h6vF0&_Qda{AXH1N^0|7m3eou0{dv*@njtB^=yM3 z+UTgbk+i5x93HEd1rb3qe$6HG=+3@uE2Hafa+8`B;&eGH@YKPgazd{|&H{_qEGA zYBnw(0q)Mu^9z$$dbL8^7UJzXs7ZU?QGbxT$>_M{fWI^iOkntOm6eqNT{!&tu{w3} z`DoSQ%dhr3V9_{PSruw5b}j?f5KvRU-PT_K)uBTqu*9sSKp8kUV={(-2(W$U=^aes z^N5Ic(y}~d2Y4wkKVZA)1xoA3R)D0>E^D;WLEa|p2^-B4VFv;OL(#R{Lp+e7U{>5l z;{N@U%^F}TQfZ2W5kffYkl}xWMK}yjba$cYHM`ZVr~xVw@8HtoeRTJ_&EU@;fHI74 z5t==tj-lD+3=;(nILM3L&5dh3xzNZtE=%jjw({IpEK^ZYP?-H zuhhN)zoTJxHei{_VrUd2W3w`|ZGlT889#+(4qNJq6DSbCXv1tY1;}`F#Utzu9;df& zOX^O^IbAfH+M5usF}MDJ>748^b$(!1iHe_Tgt{mdFK?ktb4=CabO)hw^U%v)Hv@=FcrtE!5F|k!J1n~a-`*7e~jnkI-4)|d6JJR)UmZM?(5ykprjbJ3n@xb0_aZYw zHx-A=`M2=>-#)(QkHTSXLUP&G*ev4*@vp zwYW($Mm9EbR@NBK^KGW%o)_keXJIU%JJ&N|-0YTeK&1G5X{M+NDDj0lH;U=&j{eDl zT(vqRGo@l-ZSA!9QN3O6bbi1|g@@LhgkC`4(q4S4635)7&j6!3D0|ZsA0@)1<$)Qq z(qa(-?q@K21R&pmiFoxQVSMa!J(Ty%V`wVYfYx3B{|c%!2=XJpYVDt^GeASWIf*L) zM?Ocw>aWj)yu$&cIrReN+)Kk7u;`$|lPyLlI%!YPIRUpl@ILF!ZRCv^)KDj;HUI%+ z7SLM4s6b$(X;FBNIn9xBl7{JzNHm0ORKOhNd9s7gfv5G|x#Gi<$vDw;miuo8R z+zxAFn-acQJ@+esu7tJUn-N>J^5A`h4Ko3Hp3(h197Lx*B&i=ca{2sP5b%p|jYdG5U5y-G{Aq84hzv))q(8n z%gY1*On9F@(trUI4$!RM7sShOv|KWg0iMR?PC*<@D+04_)jLDay{w#^sMy$S*Et~n?Fk8%*rG(AZD67Oy-;iLytw!~JzKds77q`tT4TbXM zm0FK$HZZ3G6{HMOK%V>8V8j5z9lCfZEe8fQ06mBiyIgAn2OPefsjRfdyuHpW22WwH z!~52N**jnky?HxF3yer8IM}XC9nOQTo-*w+NiBNFyw-N-O9fDY(ei*} z_cZo2%_FoRs6c^%f4dm?eu11ovG}oXV}1Q6@Vc`mCr?F6?Zs4@}C`6Kc9bBlw z$4l()5CR&HdLyrBQeIwyYt5sJy-|6chWuEweC=gV^SSZ_;6HnZhc^J6D>Kb@h`@Om z)lcchLeX*w1Y_TA6B%-;hghJBoU?qAy^FgQrY&@hp;pT55Fx6#*(L+U?+ZYK+YB1t z*Rw;AaX3UXp!)`jpUGl*OnVD}PcTpmHGTm%>@B|&5U$;?4?ijuYW0D?_d7In3&<)D zwaz5k?rek&wsjP^fcx-6!38KzE0xEk9qOJ%GxmUki#epUn4gHIiXyLY-?RnfIao6A zE4=~wcn|-4wdusv{ZUFSypl4oghEAi%b$p!953E)4JH@a<9Pr10Rsk(HshX))~b^3`J0J*6MsnMTawz1v_mPtOdrU* zKAGeh1#)K^Icsul&smYQBt*I(=ii;E)} z48$6&DWmT$m$ZOHDOT5rv9VBhxgQ4fCTQmd#8l{82R}#J=$$>~Cznre){g4A+?(85xQXA7DZAuzQqTZje&%V3+8XF+A^l$<<-QMSFP6NRGL!a zY<`_@>f#C9F6fw;UxA;`Rzu4$Ebr6aW;W#>FgO6}N(6AIG3$DDhZ3IsdEee|(=#K0 zm4`G_{XKAa1?I5=Qj4|zEO1H#vl$l`E{)l~hQH8~a90HPQUM{c{sl{U*e0cVtRnPX zEDSt;N~d0=jM?VLZpT5TDx2N|Moi(R1&pt}z&>Cu9yeU&X?Y)+W}A=ET{mEboUau( zrPQw-cB}LKyLXYr5t_GI#kDCi82%GLKh{K()ihHs>a*#idFkUgItL%`f(?FhNJbAv z2>+`A!~ZGfsGt`;9pIDzF|n^rI0A2$NWo`g6Mw(vf$s}dncm#oU|br)3pj^?&sM-x zc7#<2$;cj&Y(`F({TU5tz23GBf~qqL6U`vtd>y z3AB8vaENG(&MT0rwcXhaZqT>+x)H;#5}Zt3L*(V<6FA-Ifp?9?bmk2hXCjwQ1XEeS z%b2YISgmLCMZdZ_=mc=@n!aQrQ^-EMC1oLvm63mHD!tisk>0@aGi9aCZ8`R9FSS8L zOulrR3_pA>_g^Sp4_WqZ|2GCMk01IOy7z_z#YAIVf#F+di?##B(Z0%rhTU+wGx4KtwNC=qQ(OI-=0S)T4f|E4_s=km4 zhjbTtX%`k1ojc&$1&O?=oK#&f|~<>?Y3ZJ97|)6aHq7)<8tQB?g0-@QWz z(|n+qSH{L_)>=cSkEqS9_BM{eB>6@M8jbbIzqfZ+M_G=Gh5v~zQ&)2W|8D}++<}eV zBZr0tc+Sv-1f1}Q-x4&tn~J%z0u^vM0z5wHMZoiF%EWlrPPDbHvZd0*MH5R$MoIZ{ zgxM(J(*ZeVt`IjS$JxeNH|!4x`#CzL41os%0G z8O3;OPaI@}ELULP`AAN-Ip^rPffZH{h)eYyn^%HLUA&C0{{@rA+Hm2zvF$HOo}u#- zK_OT6$J-7+L02v?i?=pzqX$NfJ~A@O{R!2e2NTGmI;#JIunV>BX(X`dGBsw)fsz#6 z6P899-FKj9m?OP-0NU12z}imcE9vwMFIJi?imS2T&RZ#34h#>6mX?0nu;m2h=W{pN zemN!$Fxhb!^he84S{Z-;t&#d!+%*4!gg7Wp2h1Zl^6Y)PTK)Lamx__<6%i2;l>Or) zV9)N2`W_JmCu^!Kn$qF;50SM`iMQRImc5z_D z6c$R4gQRG;@bcB`*F6&x@OXH5-{j?i!-D-?IhnK~(zlv~0-8HlS0GPn6`d)?#)83^ zU_iiUF^&L2bp84UU=GfxY_K&pHnwDbF99{j{&SY$5IjtA9v|7{{|B0_d4IY{9m;eu zdu*9Y28RR$2mS>oZGSw42{AJ>BlqBrP_^6AG1rxJRpVNgN%I30O>m@CYmrN#=$r4T z9)DYFt2g=ZFmOxcVhRcD?d|M*GTpFND%1!mkdUw13w}P3f4ZJO4t~!I`V6S$JpS?V zdS`Fzp>b?-(qJlhw@|Gj)`EKh3=4PuNrcmux)D5d77oP;iiwF)Fq|Fh0u7-&jgkN* z5(+NMN^Z~ThviV|#0M$%jNgOFyfy#mQ}oM&CAgc|<6LJAn#>i*7#ZIJf;Ow~Bg2cl zBqHGD1J3Rw#`;yGp|gdmxOCUhs%o%ArASt?as7OC#6z2JdkS|G zm!R|BPxJE^sW)#HWYOWV;V%tiW6ct?6Vw+QEo#gk6_wZr*d!|IixMZB7HOIH6ZaiN z-eOz7#*Y3f>u9Lsr}KX08jgH#)GO53 zf|7Msf3G2d2_}mtzRw>%sOv!9MU=kx{_>F)f%xsKAQ;gv?YjT(zEzmC=Hl%ng&)?3 zPNB1uTo-yI4tHnE3+~oiZ1#l*zR>JgIB($$fvYa_i^K7n(UFN=dk*)DmuF}69m^v` zLjK5Adv)GLMatjQ0yj2(QYz-HY;XIwF_xX2oRq5arf7xzM2rg8mi6`yC17+u`A(@B zLq`ucaWv5R7$BQB`4Z(-SNe|exm&XOH@{8?dHD1yri$`X1{P;7W6IUsh}l`*n)>#0&f^-TGG( zUZnBEN~y@?r1uU_@z}Uu?%^`RcjxUC+}qXFo4ceEox;M-#1f^9dAdbQ=cdL7ozd1T0gf4mhxcMi5Fl$65jfS4O zwX6oB=7)P29L&sc4D_C_x?M|_%*|&*$}JzcBvU!^W;X|b9GoG;gW$yO^yRARfqu25 zMHP-c3(xc639<3+jOJ#yKPaME<5Dr|(O8N%s_&Oksu!x>aV`3@+Buz;iwWb@(>-D> zwZolvGgwJ{3VaCSaaL*Ip;X zV>KsfULIjY(~rO4#Kh>Rg>)P8U_X&EqicIrAec2jA{dRNSd?0x#}27nUYbInQ@x~Q ztXZQ54%Oz1KEZ>M_}rfO+U}PxrrhsQz_Y=1-&*px2eLt^@VzYwDIBPEzr$pV9dD!i zroSJrw!dCAUG^ue$v<$7vHgE0*ArTVPC$FW4$+1Xi2diw5-fT*FI zUtkvgW*}FN!>jF#hQFw2dZwA%%B1f-hlx#d)1U{Wp{6r>&2kyWp{!XzP>8Y1Fj1;(y|0Xl z@_W~Q=mtT$MnR>70i>i+N|cf=DQW4UTSAbMpCTe4G14s{-5@E5bc3`5L+21@^FLqS z_rrPD`k%Ab`{}GTEEW$lv!A`6d*5~4_qCrQFD4tT9-z}aw}rPCZD08uFDzKkb6D`x zzYCORNyA}kA`s^1zp?gvu+@xz=9e!Z?@^ZWrv{a{4rP*}qI6R2eukU5RfmkzUW-y~ zu75|kv~_f_@*0I){wzNUd-J9`FUAmw4|)6e3ZM9A7gAka4j$_!-LB&*!Lk=(d}(E~ z__Ej4+uOUvR>-35!;^_hj|aYofAJvi%>*UN$!a+3CmA~U#r)G%$o>_B2BuC8$jn9k zaqHwH1AZu0yyPXPZqfM-fOq+ES0j2-R=xJe^b8E5u8JZ!3s%PX8G-w1hfv# zPzZ0Ax!1IbpwcAt*}cb#KkyD>BKhH07Nbc(#1LAzX1boVkLtWc2L*dq+(_5wVM(ai zbwkiQZ7%Qs+Q&jZQ^RaE2E%{cda9AH4akHd-oMvEK8SciK+!fnP8Z;NTy9@0%t&JB zFjoD2Zj_jWq5;;=2fLO-?~PfZ+!jkG*zm%jTM_F#sl>+GI8mTbbayFvcI&fG)UeLSSzMY#0utM^)`V(54*aN@Fg z>l3Dh8L{=dN&zShQ3XixC{|wSDo(^X7wwx|*tUlW2XSP%>+p7sNV@G&MtV(}QSP{QY;P{^%7qNqx;ej8SACyF6gG{`twS ziFy%@j+=b2-Bo>cMlRksS0LyiDJfazKS?0=4}wtXAM(Y}<2fZ)SAi^KmXUTuhbK_K z#l`^%mnS_-JG)0A&CSi7;=mPe2fKIyg>o2mbLjc{JSI}TCF(r~<9!+515OJ|i_+T6 zGhY;ztd0)N3!^=Xb%d3-&BnBD^GRdXAvX_?d0w7vS-*xR=Bbje)g1@bvRKD960JyyLaBcjZR2Tw7M)UD%y+~d*8QG<9rt29dt?n^Z+q< z&>t-GPr%#zzX&rChqo0799aKs0OoT*X28gjSu=?`O%Z}wX|gL}L2)cH zHLwt+1na7i=rY{YazHVV;uoEN_5AMp zdqgJm+rZk@IjN=Md|>-utd{*j$>$T*VD?J zSJIY;TI`(4$h0qfn$S(W?fOtB$>^c#gbKXroOsUrLfA-TNLE#qOhrXyVRhA-RY2(b ztNt1Zm+cWh0p|hZ4<9~0;!bGk>qC7WEXdCnP#0=Az7+JvcwduQko6iE&KUwX?0Qch z95k#R?ERIVjr3J5S7?0umN;+J-rLvLutA~gv*1Y6B)i1aDB+E~#*06HQ7*B(g{7hK z@tuPOGDysURx~58jh&CfLkS6^26DTNu~bz4IJMD;yQ`~QSDdQ4J?M~F_pK^)2$q-U z9YQMxj~UjUw>zl$L@D2I!#DGe-&rN0)U5xZWyVHDi}NlrtP{G!W-b6lDeIHU{#%!< z_929)r(*b!Ey_AFk0qasAgyB ziAvT;TxXeO`F4AoT&07QL~$mM|HNz01>vQv;m8IF+vA9oNQ6jD4~W5b)&2DvyiK2e)F*2%`VSuszsE=pA`rg51%9@ZBh7S^5KLCkJUr0wya-8NmwrA@w1 z56#}fnvjB;O+6wPm41qQiV@70iZ8D_X-L?NL(gV>zKoxD+xvY_Q}{Em55Bp|(vw6s zb}HCoo~2yReMGGYgC-QR4@K6?ZGD){m)2 zX6sH@Y~2Sda{VojJ&9TZBz|uVkycqsMs(9|QU!xWIqvE8Qj(;N#}Pb?3>%LV2SOG z=&aX*MOPwtDdTBjK^YRXk}L#QYUrOqvP}F|1G4==Zu&@+o8Z&M&HD=Rb3xLNOC8>c zLK)85j)YILsSxPZ*fvRCZk|HsDO02Ju5x*c@>3kmefYHJk=h2IQX9)6C-2zOMbh_n zeRFI`oBr7+F$XAOehx<_=sh+>f5VT&cb+lw^It}0nGexgTuBgg8Ny00nI$oh#w|+_ zBpN1vlF6?g&C;AEXJw^RfkGWHjewq96Ac}m*!HMN<*TJB%D#-nR>EzjU=<{h5>Teu9Eq|TSe6} z#?*q#FF$-nku^(^R)-;i^S|}Z=swk-`m%cF!1G=Dqq3w3g{()uW9gN`0aNY#nce z%b(yte5qWoD=Mhf8^nn-8_!+2jL2Z7cmHe?b|v*4-4@=+(!o^aZ`qYJf44wcMs-;3 zYneT+%|CrK-rCni17$S+EyYubKAiY|n+(jAO{|{|iH>VI9S-*ny!1Vv4@D)UWVf+s zo!!ca&aI96Z4$ReSJd^CL{wI%NU8KPjnO|R`_SZdgMjZNXXBc^)99-sp596t`Ukb~ zwNComar7eMq#WdHe<`l`I8<>_`!qvER?(NCz)iH;v#cV?V0Ws{nT0rly;M z$+(Y|BJ``&Q>IxR&KyYo^%zC3o+hNGLXfJ|Na1*}ta3IL^MosFVxkV`xE`C2Gk)sI z^Me>t{-nO1`{CtnxBUZSbVp?HKZyZ871Pe&8 zop&FZzhD4s+%0Al=9NBA>=DJPwWer3;aEk%pi|RRY~S~J>$W|`t3cu+m&C~f^@Yj; zHz>H?roC)$2O(FA6~f6il3bdUXvf`;LS4@PY{yeL6^CShOv=E&jgNe)814VDSwoiBWCw3m2xMrz?9l?Hn{CJJbfn`cXvEOevM~* znE0=$zB78VjCPEU<^vWaa)F>?y7cI8n3*)N|8j?muZV2&tl~G4lN^{zoQrz9js=AmH+Imd3AW!&NtdF^3_`n&a(St!i(#duVT`s=!m=`kXbWf zzb&LJZq^|S>KI}0Njylb0e*8S=diQemGT!VX6L}Ov&Jq#%llTfKnOCEu8M0T2(%o~3`E9-VgJo=@3ro+bBG>64ohVk#_SX-9ph&Pn{Qa0`^+lTTCwM!?$5a>AoS&EZ4I3aRj@x6Jf0(uPUxIm*`}(l$ zxsCivVko!wVLPx=>_2fJ&G{Ms$S#4kP;ayOHalb5ckDuGWqEMn+C0<-!QQqQHMr!> zk(Mc1wR}z_SO7e=7#Ks$?(w10Q8<uI=0pl{y|U%5O}t}R&d?fa}96mCxn@z6g9?P#S33F4sE*LPtbpLsrC*S zO#P!N5hD@v92XD8T)r=y!@3!q%|%0kK$B>in1uGxIX>Xt8W|-K78X{Gi*zE|4auB& zDJ@)zL?pF0zb9}LRQZ{^H{LGu3nwpM&ius^rj1e6aWEF`>`vP#_!+L9%hbyUSMXg- zIP@QSXhH{Enfn*s|6H4X(4H6?#X$Qi-a3zENkIO)SrQb(L}UGb{CTjw9C9+Wcx3x_ zDii$P+3sL4tJ~c?O1ia_Bfs}BV8jBrH8Ckv8`qwPRW)dTes0!V#OWujwAJy!Ky&Bd z`F}bSht45yVo6u>`3-mj5n>Usq#nQnV5z{g->~jy3cDOK*_ypS`|?c5t24$YlzEoS zevNrg=+hgzyZpF4S>WHhJ6X6&UZJ>VNlcl%r-7rlo8X@qBVjB939!l7$2d12Dz7hH zb=z?h2MGovN44B(0#>@zrKbrd4BNq@~bMKg08 zJ(KRcxVgP<)4_+s?qXw0{o?JQTWl2H%jX-pS2+n>@^4isSJ}$)^2HthUH|;Q@@)Sr zUtdtktAz?V1j@FE>0=c?J-er^r-!Von;M$6mt{-1e%*U7$CuRJ*@@>?J2N!P#>P{X zPlrr-c5mH7e7&zvQ%7fI9bNfWn>+mXD2MlytW8nWK) zacymF>+tYRDxy-M8&wMA6taykD5?x+SJj-IsiWkv;cz%-qKcANcx1_+Uyydb_LkF# zO;kz>Q$u4T%PbjNL6RXTQXpwQOfKYuL1 z(~c}D^MeYsxo@|Z#JCj zMjRX~0YGuLHuNDWX$e$za&mFW^=Et% zxe}s{gQA$*SFvnM4b-v=dBpK>KV9)Ah%GMnyw}LrSzj2&f-;^LYUJ>S%Cm(4o(xby z3qhTCJM;2OLI5i-lmW5?c;R>&HJl48D^~kW?)N@*3%rsRavNz3Dk0W`f+G50c0sqe zxQN0P6qIGs<3OWQ#%3?+t0zy0$nU{~uA;suB3l>R-~2>5#vUtCJyfi}ULjm9ovk3> zM%HA5d4{{QKWGP(>#Z<5yY&)XxomC)Tid*!7~|Yx_1`zD^hB;!CsBQ~<(5h( z-k6rIX(m=yR($KjqHBH67_{S`MGYHDgIFKw$Bsm;B(y&d1y_6RU#PaeiP0fUraIpM!P zL|cM9^~PMYt5;Pt`yFL8%s}eu>L7tc*6XpZ;aC4mwsG2SGn03dosDwRe_hk7G>vyw zU^ULVFDxRAjWh2^(Jr}i_vc5I>~|{Js~G&PPF750WC;k_KlH7DOOAiGLwNDhhiv7| z&2I||3f`ci!p_&WuaFMe7U~Eb*YGQ9cKM8OZmjL$`1UUSO8D0~IV>fx8Gg-3Pe+E{m zTt53b(SDN|xQV#)$SL|a__rXi*YigIdSWzw)%Cz$?6ceZF|!8CZtb55F{;)xk=51K z?jFIiM2b{#%~*gOH>wc?`1qupOfQasCDW*@d(@MX8a34*LKA$*5UU9Gaf|m#04tCt zN3@W^|E(g!DMW77Mg6BH7k-h-_TNjf{JSdrI)kGN%u;{R{qwW=dB*!j)t5G)??Wt4 z=_ngM-u_bXVI7m>iwnyvUKUtR0k{8Edys~)@vDkKj_IO%;r)`q{{EIV z)4(CKNdlga>^u^vx~YJj#Wy!3UJ+WnA!}WzxlJ$QgZ+^=2$o&&8+A6rbk{YAEoVl8 zrjZSEE6W)!x!>mA4e$0sR2S(2_zTnnD2`u%JK9-jrx4aZYG#qRK|R*kN+*6-7>_83 zA*8pr*Lu1z=vn3RiETmpSdnvF{x_<@<`Zn<=(mO!45|!%$NG2B>Xkh<(F1%~`Y&EM zjba5N6E_ei)9oN7-0pm`4R1D|l-Rxv5Qg}x3nE~j=R+yhLN!NSRVOFI>Wn6Il&m2v^`4J%hm(`;-sQl8K$6Mkh39z(k^E6? zSVcv}<1@RTzDk&#PzqO6aWxRft$+G8$zTBg$sPQ9o0F3sxK=+uHiOI+Im<&*h@MrH z8RVXe?7L=XSpowCAqY^tOCI-EL^6oeul*jTq-2c)*5=vXzIY?o7%gPKrjOf0h(FuXOS3PRz5mewyxrAW12y-I?LRTfWMqabKAg zHZ$nmCsR|I@7#rjy?=i*qJvyu>>t$y~mTu>0$C_eM}^4Yu0SW^F}{M@w;D zNy(2fMxsFvEK*!$sanS)NNYoiAjCpuCA&~mek5O*+^$k|m5UpG_b8lm2=vMPB7+Aav z7ft=c{X3|K%Zv-x5a$e@yQ=^P!Sr{>_Efz6&-c?2{6xd(l(^Ix=2U5SM!*F6*vZMM za7wp^6M_;G6`||2`>ISObPeHdT}{Vj@#G4qR-K~19hV)XRc8#@@1lZ&+7Aql<&Z-{ z^(Aq-g`Gz%SM6n)?Tq)myu7-$o1Nt2%UD;f09SUq6yQL%7*Kd=ZDp}n$tCsn>(VuA2~H8ghq}AF`AtrZep5FMjv{-BXHV zZB1M1G6+Z;{Ou_;uKpC2GPV72M#e^j{0@sOz>{(YK1Hxdcq2+W76Gb2>va-(_=_;X!U!gAurT2jhWJXrF@KDy&6wK?f&M0 zFBXe_v;a~D$pZGW-JodGwj5K@N4{2H1;s>Y2W9q|AzAMC7HcJG%Ji(xm(15w9tfv^ zcko9LMV?iiCy4WX&{$qMVG?RXh1h;W-S&TB4+f}Khcz>p%f>GQtFj`xFt9{yR1 zz<~y`(;WmyK4W~|A8txx_xJXO0nvKb8v3&@XI^5~0?;iF+`8}=?iveej zbd@i471?j++t6m(ymUT@*^HgLI0J`w;Fdo8}CB{=f(b-eT`q2JM# zf`I|Uoc{%xypn=wZAnv|Rv-sQ?mbN4VjEuGC}YRCM2*s&m=@6CkdTmU_rmkIroR7b zzUt|?1K+xl;rxi_iy9YJ8hji8arJww^#?+5NsRydfD-sOXVXp983HXGnxoCx(A%MJ zT1H1{*p*`B|CU>xEFl=dBp+`SglThkR;bJ1Aj`1-{S7(HzD!a?WUS!mMZhV|b-loM7Ck+{y{y5c=dLdm?QzJClyc#(7QmURH1Mn8Pxw&Nw*)D8s5JBC&1K;(Vv}8Ge z8kMZup)72^ap>dg+t$}tsNnJ0UaMFam}91;?Ye*c0NwBaogP)3kZ`?ATxU<}(N4c| zPihv$5Ms5h;cfx7tktuw5>4j^?xb-nF)b|v-QE4cx`o2W$gh>u29pNs%=8m~0*3zC zYH(S^=36xmQ!9Nlod|cAlf!a@o3<5S5a=JCy45lhwJ+^nOu;}o5+^tW2n))>S2X`w z?XZAGhg<`>kjq0jMS9>R!*dE)_+a8w98f~BT33w}HmskIe)~2!k`MyeZy&IOrl#6@ zItH7j*1ELUv(_#A*=2X6&^J#|SH2lY%sf)eq}ai+&^Kz@YAXcnvH6CCb8<7Y9tk=5 zkH{0;BK_0bz#+A_w=eVQvj)`&B*9aY761HZ@-sEna{P-BfA(3N;R%6*^Tu^_4P4CU z`LEn&M_GdoT#HU@?~Ywf^0ZsOJq-AP&U?JmH3_um7FAr{luot}i_cmk% z7SX%wo=-(noNT~BIRc1o4S&pRHNTFIoM}my(RNepY`s?ss=lTMaIt6fP%8Il&=*~} zI)*xEgHS-uNH+r1@T`M&FrdSVrKr_YC8K(KRqnvV!vI!`tSdO3PW&vP_!+e}iZZI7 zHw|MdBL_503y66gu#k({Fg z>s^QFl(aO5{G6%Hnc4@Jr$ZdxN8xJ%cLM40DPV6YcZui|_`&AUW1?n>6*UdQ8En{L z#{VIoX*vQezo-jS*A0Bt#4!LunbPJX@x8sh>j7{qk($q+$LP^D+wX57+}zrxo%uQw zkV^dg_lQ9|4H5|R`PO3i>KPEC1h@M%0r>Kdik;3!%A6uZt$(Fg*8vLkOg;In?rJA_ z>R$p7EU*kaUV4|_SMlfvooPVG#xT0-ul3q$T*B&^&*9k^`glWYyR&=x>NVC7PC`mb zv<;n<(f?rC7wo-oGZqn(__jrCsH&yE%p7G^##%+#on z-SFK~E{{`0hP;12O!lzTAtrkZ*IpfCH82oc@*w#cCl60(b@egX#+z0%St~26!s_8a zgN4a~hKBRMFJ2t)AM84v*Ekggd5EqQ3fp`8`7FJGjbD>8>hF)*7fv;NE^fZL71fUY zF4Dg7yw`%1o*x?0)T~KOdb9Szn_OM`((73&|Im<$!!amqBmZdnE?#)vKNM)Bg++AS z6Hul0J1j~!ok0`zuN05tA6I>O`M8$?EOyj z1AienDvAk1iU)|cz<-b&g(Z}qfj^$ljDJBOWDto@Ldvd*yYnu}*lL6=%cPCL&uCs7 z;n9^oMJ`R4^7y;J-qGIPKJ{8_?2Xher8gyIRl6^RbH`5|1%*<55ux9dAG|bp7D>B* z`0Gq%<$I(!@`;)5H=Ydi@7KHR_wSEGd7Lbt`jS1<6tAv8e2FCVf&Lu=s&8uLrzhA* zLRNuDAD;P6j43=9xHYHJfIC@8ddbVMX4>-N4v749i3FVFD4 zyPle!Hn6sqHZ*+q_U+rt%gdLqUn{=f!~4ujktL3mnw3S7mzURVT;|yq4~2r?4bx^& zt6S*p4Qg-y6uom|WN0W{X*r&&Qh>YO8{IZHNA&IT()ArVx!dg}^Zot(dnzitTrVNl z1TG$)ky0bE!oos_q5{2U0b*X~_cSy?SX8oKRy#wV*tHE0N1W|U;&IHq&TxKGs8LQC z78b_E#l_@v@9FOpO2D43Rc#wZuZ8;!KA2K&Hb~Oi+UiiLlqHFyt)oM&*Te@IOy)Q0 z3L^&5U9+SmCr9-0@tK>O`xO?Z>X9QYEu9PA^j|!ChG9q0=FW~(W20m=O+W0qQb&AZ00Y)g;>wmsbmZUWMq&dqF}TS4#Jq0 zW4J0iA%b_ON}ZvEV$n1zOsuR*>T1Q>+~9hSE-v6*q&{oai{5Rmt-iXA?$kB~E(Z(m zDJV+Khu^6ds(%N8<##`Yuz37NeEOnga4;Mh4Y$O0o~N*=XltRd{+c(lKR;2nf(_wFh9lTnePJI=d zz=vlC1SSX5>4lv7Es&=eMBT+Y^))UBy5Fl*;>YTcnjF?8lXo178I`hMfUF%^OyYIv z?CV1l6cqgW^((djHHfG`6pC-s8@0SOngcH4w0Y_DEKj}k-K$rxEDwH1N8^~9n)3PF zC;s~NjE;`Z_4+jLE3^Ox3kRnHg zSYBO?w5vrxd^*(N=IFdP;~yJ~2QrpUIyWo5`{2oBzDh8Nd#TkVgT?epN3evXWV%7y zPe^8Vw&aeYq9TNeh2>97ZB5NkmK0t{Xy|iv^mUL`mUe;#oOmFj;4oesEKRRG3)E6;G$;3j!}MufXkLn`hrbjlD?Gf}ZLz;^FZz&DW5u zEOC@(Ya1JUK3Aq{+xeCAz1flD%*^+pGl7AD%hTm%d>-d7tgNi^)nK}*kB9O3^XCe0 z`eh^~-+lP->+taKNhS3&J919WYR|4sVG$8~N5{VEqTQYY8#UwSLn9-9UXhD}GSJ%O zbrTgMAubMS85)w;j5&MQl^E&j3J4|SECZQpJ73o!M(UO6Ok{6wugC}Djmj^@&(9B@ zIEcre}GzK6w;ee05u`l`o$2c@wt^jAW!-hTua_Y;#e zEG_MAy~{!8*ci5yloTC3eb$27gwE3Drn#@L?-zUfzu+4ncp&s5ThnP%Q|gwJ#WFdv zNkfy9T{AQBPtgfp5)l5sg{-)Fcs3Gl3D_+^fqOWii)_5eEeyD#q>VsQ*K7}e z`^@)utjqPJKDcU-sjo1((R@>*E?*adb|&@yqtMHW81ZkuWajh{5M-etO`fge5SMd? z60&E)x}PxRUm_JzyiWa}|LFg_2flv(fA|-!DJs)yYPkMHMl!QM_WVzK?$3{rUK>Au zLr7?3Yg=3*8}mE0BJ6vUz|WsQ-Kwb8Tz!>QQlqQFV+)r{$=QlvONJB^BI{Cf3T zL<}RxW{1Oiz9LJ!>Y?fn#d|V2@s{rHXFB}+U%$4rPazQ#CyijpxOPQ}KarM_TJ@tu zM*u}=<+wH&)a*4aMlP;5u~kKx&4|gDv=tgK1FvYOz1>~&=~n+_e)o}V6)S&EIfL!| zHqeP4Y%Y@!Q80f;MZKqosg&cA2ZZZyF1>y8=8gGSc9p!7ZAeH+u39w-Y30Gk#Raci z&@HGxQ8ide7NW#aP*Xp@!0N&m_^RGy5>CWRbGMjZ7~Shoq*a+7@)>{YU~SFVGv%_( zuHG8w6v2mtq!c3vZq%GvrXEDc%1sz+rMZ>*1J?PmTX2=^3;Zsz9Vd^8KXC*dW z&Ocuegy@n;P*70#+wfN9jW1x1Hs|QhyQB7jB;@uvdZJ_|y_&K&o2yg6ks%gFGg8NW zb#)`vbI>*Ih|lc#LwF_evLn{>ejP87&nrmqey&ALPgdFLp<=vLL=1aC#+UDVB$XV? zLC#hGy*)z@HFXFnYcV!C_JT8oH&&)ZM(3Q*7gAUP=P{kjRg4h{~b6L(JYFi;W&@GqVliG~i0TU8X9_swZQZEUA5K@nw+-~BVe z%FdkS0$Z@YcEl1D6{SD#+=VT6dF zU>a;BY9KG@&Q91so;`p57GznzNK=|=ftxbOm^PIEb;9tj*9{F9vAY>x?XioTfNCX7Y_Ta+`=Ml zu7d+%14%ri)pB~^V7Zc<5>?OF*X*x@c9Nm`FaC6YI{18VhBlO)ojw#)Wry3f=gHUn z;OIt)q7#nPo57y=)S!LNX~)v9=ddZIvFg}w^oZlz(xOq${aqj}FTdfcL7}CkS!tb> ziF0Nm_h$PXf~I(Je|PiI6qD0zq(@dvEWrN+?=?P7kHk-u8Zf{ zV%7VeEX%AbD=WFiR#N8bZ(I)MO%}i3^{4QLE0BxQw7&-D z4{9G$c&Bky=2MsSA=_hlk#_a}h={l5O0mWZRQf9S!I1z}$H9D2s93kI^{h{Ay3C&S z`uduP&-2;A?1JL7T112=_ZF>iTdVp}p94c8clc}-u{Mv#_k$*Ah%}|q#2j~Kb{6%# zEWk-SK00007g(NxHcx+ZpY!b9;DhHgTp%X*_}U%i@S`U0$gE)8a;po5tec7@xIYN5 z*~jL4SKWrzG%u7|=PQ~M_y9Q#Pf#9f_8&5}`%ML*v3w0Ia&q$Y^o(bys5F1nZ5Qf# zz!`%7ggXs*BzD|f%S;q%qqhjoRx`U^%GbH<{hW-p0x#$rexYL#XWUbkg(?F2HhzCH zXRH!Q&f}e{F=%g0rIBlMIbu}X@RpR98x4FV7GZO^2!%Q?4|zfL>sL0ZSVqK_$_EG-l7fqhr700xT3ge<4d0uMrX-k8 zr6L?Ix~`E;eupTAqqj_6FrV#AtVWiuZY@@)oEjLIn|H%gyni~?I$X|Oyk%mN-*T?9 zos*tq(8&X}*4fz^qFuY)^G}Pj6co7?|KO4$bJ|MoZl{<364?93!!Gt_YxbNooQr1Y z;y6l?1u08>zrcUvp#pUw0sPrr#x?NSDI3fVbr1IPtStEHz#vo z72XSpr2oN%8yg!T#QZ;JDlN$)dt5IsBa{brI?*wR_&$R1NWE$eZ>vm8Obo@0$_$rY z{aMS%dNWyUU+{LxGXk0;simkW?Cps>5l}d}T$cHCbtmne9bzW*njE0tS|H##h*svS zxb5C>EpqtiToB6sOUi6kQc`*x_z#EMKwco=a)(wT4 zsn z^BoU0^#l5I*Tgf3{_g_XY|8A~?Z@NUCKmo>bpxHpWjB*8#+Qk?hbUcKlA%sLDztQF zvP!L17u@2_Oy!Z+iqzLrpRTK@F6zgkF9E7*cb-bY#8{D5EP#VwP9|hD>()rnaD()E zs9M&rAx|+0`fJhP)Ac?ntqHD!I|-zSC^e=rauPk&|H!+-X!uy;I`Ru~R=Yx0Pvit6 z1uBEfY@M&&p#d!P^!$ru$Z4>YX>Zl^e+)v&EtNZyZl{~CVDI!KR->zR^%%^IjdL55 zx?qeq#JhXZ#nrBNHiM)n$rzOK!4^dQDM=wJUC)O=QaRf%2kM9cBa7XLdd!ubYdTY@akEBd zNNL11EFhMV98ywMrK&+$fWkl$K*LXw3@LXfH_gs|LCp6<#Y)w&e?DoLT+IG*^A+SL zCNbswxKhr=$Viq+aR78&C9ZDT#EX3=d9cy5Pq)!Kv|A1KrNkvwG?V~!CrXDQZv_tT zij(UERL($I!LJLN9k|b&E_w>eF{=MbD z6E;3Z#>VZ3Z-W-88MoAxEw=t}|5&Y>mD#dCJvmve2tWa?$a9MAK*}!dGV1yO0mJjo zRcs=I5%Kzr@!uEJ^}gqN`W6;FdI=n5_9v7h4h;x*Df~wJx1RegoJ&&q;PSc0@kqjES-d^Db!73ms;vV50X=D3x|W5S~O6BUFQ!C z$G257H(bANMRi#SY|lklO~ML@16UYa^-Au;7x8Z_HZFYdZn+rMFzYf6d*r&p1v~#P zB!e?*eFwMmfBzw}N4>$C8e$|Co@VGD)IkuOs+p(z1hK+moB-fVVPWAfCDmOL9Y(}< zel!Pa26wQXHxE}i{Wlf@^%whTSyECj&|e(-Yzzh}QAxjkUg}f=g-f`I89xmcd zsIp$!KC}9|H=R^vGxIwxuG<0=)4#qWA_6vMI|_)3lnqAxTeFnM3?gzA6m5Ho9_Why zH;p_%WkRFekbPBvaB#+{dByEtB*q?3Dj>}!(HUjk60<>9Q7+Q_oN>1^Q_jmkuPrVo zM|J2%2AH9dbKL$Uu>;*kDLPykXnb7RO6+0?LB7Wx(D!G)Q zIu+Wc`{M$`P?2t}JgSdIMn*r;@p~EjVwtVGON4z+GAe2-zASJ4CAYq`LcGD)h2Q(# zjMU){(7)kvea2sZ@!=0laC&O0#Ay^4mr0G z$=?kP4}+XRCAfRys^Fny7zofW-@7Lwh=??*g&(|MUZ5*%^S8J_0hOY%z_=h)M7Iv; zI+z!Z>QpdO|G$1_PR_wIKXg1s6L0^*V!!PJz62;#;SPOkx`DbhE+GNWy1Lj`(vF)&Rb<*&*T*19%? z9QP9An&W_5jEHG;KMP`PPVNpE_-8&<@d^$1{*$8OA7Oq_U_%Ia<2(PwD>mCBn*K|Y zv9`7j>?Fa*`TXfqJK^X;x!L{g5&Y-7U@_v)UN6{&i_AC~befcDW*Ka0)nM<)m{Kd+ zKHyUPfvlRaG+lZ=5yK!_IlLF4)2jB#LyA|zO~S$=S6gs@2r4tZRxJ@N zEp4&R@!EC=Egza|C#b(tJ6LPaACC%8#X$@ILA^G&Pav2dy|tQ)KdmlSdZUB{zyBmAHe4Yw z`lKt7qWQdBmx|MFeywMeDyouBN-8!6oJhpOcelvk5HoSGbgu5=YjSZro=ngS3;X41 z<&dBgvUOL=9L!d`onF3GDNycMSU?~pCDp99%sP$BJ8>V_so8KLVsmS5kdm}{F*Mcv z=37*hF@)o`^7}!y90euiPZ0m1N;MaYxxetgUbqaJAI8x=NxF0GjfRF57Myi$s8_w` zh-Dj^X6j9weDiShaG0c=XU&~srZh|@%+VaC|Q>mPcn&@yZ!blwQiH=^A`VLJbb39 zXfRW_;U0!~Bi=Z6oS;I06gKju6);8OgB&F5ZsU>PMNl58Ef7(AV!q!Xmm#u=JU!i| z8E!`_$QS!JLs@2=Bz&%^WsMCpGd}u)MxEiyZt^dwnxy}^_;v}!*O)Js>D3(J2s)ytc#nf;ldyhXkS_u$w~`@mYXf#w5!cj8)S%nxnFU6 zf|$apUqTCKNK~6z00*DtJhBwpwKGO7uz$-eNPjJ{b)G<9O?Vu?3&!8Se;Y0qJhYD* zgh68~EsCqZh}F~LZVU=BK4O%bDzis(uM0{+(conJT7H%dat=XUR<`r-?4ca(Ir=(G zhVaVcWP&gJZ=6B~KC2}gWISKRsOMPEd^WqNqDgPDNjilEy?ZxsAf7k40}XGu*oGHE zz;4}+>1b-dyYxyloapm^ChgYC+tI;H4nSx_xy?AFymdc;lpHylUapFKo+76YMybbn z0dNKgB@AZ&QWEYBuSQI2XZm18{!+Mrj3Lmh?ALYyRAaGja}1n$$e8pbV;4mGB&ug| zeb&^ur>E!k9!^Tc{UweE10ypli}|LDoA2B!WHlhHwwITeo7rglE9CU_>@jO>w5kzU z^d5qJG+Og<3d~3I*?)6~C9+DGb`qn$dvM{4%y=;*dVKW$_UWvJW(bL$~`v7m6Myq`yxUaLmD z@98ONY6Y>3-e9V$_S=J1`QPV@6ciJPxAy1S*Nsi>Y(R9{HYT-Sj^2rd6PtiXuU+RE*qz%im0J!U z9L_hPm6rJj5&w5?E;T{Cl-Sq|==|*dI8ih>?h6twam|G$8(snHc&Kr&8KK&6PkNyD zhyU&caK5v(jj2s?g}wk{69j01S!W>fpqZp56b0nNa>V?Paef7cD%9CQoR@$$GZ>8*~8CSm30@2FNiXI3!j>g(D!3ZC>4T!YU|(B9>2g=|X0zY}+aha>_?-r~u)j#`C+#R!bw@D1B=j zAgrxdBqSIupoZn%E_iV9avPbNikhp(Vc!HF;&DyQ(!OsQt6V10Vt?mz%&`K+gx z5{T8*f0lj@V3OOAqw(|SV4Re^AtfRZjuZ`Lx7-2qi;$2|duOL&wlqHE$rD7CPLy2=>q{1>+}7#KPFOJGg($?Grc1qVZ9Ui)vl{Ib5ao0uli7DDs2Klx4*kNHM$wt z14O22n2znDC_oxnfZSwJuXM+GJd#)Eyx=@bNK3zGW{#-fBMH+fwe(kZZqp-t!(v_% z^~)h&wUQ=@*LkJ-YzI_IN}#ek?L3G9)+_he8;7hM1w5JJq0wB`B7(h{3X`)L_V<*O zeyAWAC8Il-zve^~lzvw|O&9^8Rn6^=k1l|6ZP9MC z<#zpS=3sJNO4Y{HtFnY%{rVVey=sPRBc-$GeL`=*s5>;*@jNGHKs}na3)GRUGtgEF zbuMTF!b#G+SD$iu%Bx++o|!6SgDk5!IDI9PMC5k1jic10!v6u5k;K&Y{xt;*KB~xB4)j z;=8|!$?B~SK-}7!=7NoGJFSD25!hEFh5SdFUI z8Du=Z8!p3TAZ>Coo9#rDZDSp)WxMz`jhjR22i-w8;(&DT<_4RuBkOK_B`U3DO_JH$ z4(p)911J)jvOzCjryE(thJ%L}07T+mW)>$f8m$}(>4cHm=QtN>wzqd0s#F!WnmFnj z8W{}_4=dE^0f$d}SC>+iwMN#_&h{4do=InWd#auOZ>yyIbLGnDhzOyt(rhO5Ym zgSWvH!G(Qxvu<-FO7T$zbYUP`n{8i=LV2yiPNzC&KX^PTTwRi%S$>vfd_Kp`W;^$$ z3sdkt8(qlOq8xk{)|@7HAdp2IuSy*ahp;p{JnpvNt$s34nL5Wf2FbZ!E@+byQ&IJ+M%PXL$3u}Oe^lHV(m{x%K&An(%T+d6=!FvLxoKanpB z;7|m``wu#TV60NHQlSzm_Vkj?qo(eUyW)Q}?Y+waQ%7S-X#;xZ<=TlHPE6AIVX9@( zHfqmV%mw|7_n2%^U~14!A~G_vLZzxxgYLtMy>5_E)1Q&V@J}CVs#y?lKN-M-KWrvq zGQfOJ_U5h}YbUM*j@IkcHVCUeq;%5l-eO~%W4I>r`$C>@ZlFdbyIbr$at)fdOmGda2#U5nyQG?LAmu4`yW20-Q!~aQ_h{NciBL zHsG8lnn=h<8RaAp`rJ2t_qjNT^nUTKe%57wscIH|&`K?OKrNl-91N;}_@M-SX8mY@ zR@LMt1`wds;iI2Eefn~E_!fv}1?Q!&gH%hYTEHYz=J1bZ>mXxa40^Y!O}#wt^Cji8 z6t0vWI&J?gQvL>ix79!h-Tl4yZNsJ6mK{{Oa|$r3e-ho?V%gy$LWa8|wP*sE`?T-X zHH4plD@ld@Iq=?K=M;^3l_BN;@BqShgc=O|UtRc^7CPtZ$1 z7vMh6PTz2QA_2)8!h+QXz++aAH>&#rs^dV}T#Xwd7_S8O4_^__xU{UE-O^|rC&1pr zrcM&tkl9kg-@|HofBaF|T|{=i9g3hH&5;yraO-XJ1B$Oh-wiH(qSlhv4Tlb|i;$RD z&c_o{;~u+v6ca~N9pt?WA{zu!ahyEG~*b(2m69OmM{G>6lR^IjAXGmq?6T3f&u zSAM*X+7me7m0SMm9-+J%OCmH{JB;u=IeQP;wVEye+Q9-Vmvp;>UL#8 z2oZk}IAQ%QG=Jwin;pG9pcW@Unl$Mo90|SBe zVyzB=n&a$x=WiiDi2-{=q4`>79`D=I(+5=sddGj%eA#nI~^94y0lauKuZ| z+wNZdTUPw-)yM4;Ab%{mHmMJuCNsdx?*R!pU+>&8-2?5AiaqQw!#Zqmj*jkAg&-$9 zkVzT9eIT0?m9zlsJzg;pw|g9{>5@ea>f0U{6C+v_Uuiy4^PI$Na7o{8u<=Hq@WzQ4 z0U-$MK9`qM^qiZj%sZM(mr{v4r69YjtEq}#LPBD$)-jmT4MwZ&2_%vtW;ShJUOX%6JY#w>SX%#q~RUB)uH(c?~t10|jfx~BW ztbx0^P(94wA32iJ`!hE!?e=6r7tjf2(AKPx zPZRdnHbH%DG?9Aqaq_$Ml?N@5lnsF2MA9cwY5q#^5mdu`)}thMto3gCbzQ zlsK`=jfZ`jpJIo$Q8arg!Asw!8Ao*+F`eyR2Cqv7n_qQ7K?-3Ml=6>yQaW-z10)+%eH(+?6mO!iQ~7!0JbK;HC|ec zifZ3rw#>~nv~-C-B}A{EWBr>$85 zk#`MA2U)(x`QTT^%^J0JdR-c|%OA9hij@I|&bFT~vQ+wFMjHNd=dp4=ZPA|;dYqC% zi4$HE5%pIbWN*~k$iTZGnY<1E67F2WfXOm5(6`K;1DT)FpWkf1D}1!tg)|Qy^I1<0 zbMhW>%H{B5(@AtLp@%of0cU|ffE{0}8)d|9<~&AGK;sqsp6`Zv9M77OX{0Qs>uB_G zBTM(Ibcm>9(6{RoBlCQwuFRT24R7!YK{}D#+Ni9g5}KOvtz231EDPO$Hnl@#4(O|w zv1&r4dWQUV$dRt}tOtL!f{b^(@1>MhH^yE0GY3sOG$ItC7gFddKc z4|I`K-B)I_&SWQCx8*jx8ylumGc)gkW0~EyzuL|8;pa3(+ zrzD;S8CkEjT;4|`gv#l?AIgsaF+exT0jmli@-a#I(}k~4F9khB3t||Ijg6Na9|Q~x z7;|;%aRCXZU`|d+83Q_)zOAWfBxNX=7ZJ$l=|i;^ssn?A+x|BFN5}78cOc>SmIgMT z=!yD$C%6xbBVyX2C= z)Zuxb2oP#Kn}X*F?7;{T7*yW!@WgXF!tDpU0)RQAKmLTgV6u4q>I4p<)2j{gxgaLv zq5PSG#|V_I*s;#OSeW|Ftlf`*fD?GO%r5Vjm)+9di-Yl@@bLn`OR_o+Xm5?&su;g# zH5*jX#3bAO{08#(?c4S~)Q~L@JFWlds8!&F^ z9@WJlYT_ohcPaL(oig4Ji*}C=ODnAievb!}+nQ3yEt?Ms@bU4TpLGl_rYueriUPCG zPjrE$rL;CS$FET{@f_>CplrE4-1QRict&}9xktuDeF9^V`D9h7^8QMP6lh>%gYFRi zdKXZNXkU%2sWD48*^7DUvDqT`34f#tMw*JY;G{}LLSP^z{?!3-ljmrr6t!) z+NA&`b;`unze|sdgrwN@SE!D!5~h_u=49fg1Z z$-%74=IK$_)dVf@zCIEE-3JD{VDK9qKow})*+7sa#Be_L9X`ajB2IXIN{+L(lvu47{p^>0@;ml_WX1KGVLBBKl2wk0<| z2SWr=WbOD9=+Z-zqlh14$lAcUOq<`ySSpPC;`9tu@j;bh-TAt?<0ctnWo(GqV3OH>!_}3oARpfoB_%B2?U#^}GMc|$ zl#rHGChvoL;e8(S=VWXq{i-iDqU7JZfAn_r5c;ct1FkBGTT1 zt~^>PMFk!x?fD*#2j*eVXiiPtIb+#*oy$&dF~0}!WXcvht=m`w#w8HA5lLc9dViC} zvf8)8YkQ}s)LECy<)A!XPr*LH8-h11M%QDW)$=8PQO0t0lbBZp9-o$JSQy|^@`*jr z%&1h0bo;trwQbGiWwi1DSa0ej2vq%vGOrxMo*s!u@)t(womN2);Hqdi!QY_h0()mm zjF#Ne)elYDOOA$-=7J*f1 z)U&UntLxDet1t^j5@0k&U=Bi6)b=P@R`QTHUOY5y3Xh2h0BrjY3`o3`hoyt>V9fd*F){ zb{z)@=bNL!-d@)%&ZluB7@viJBh+fLcsO6h%7P@kAqEiy^z|j*Z_I6<)Cw73@t^!h z_`}~{aUq)zpjL-}Xo^v1?=sTC)&z~h@Gu|-m*(c4qoD;G7P*||Qw=jSE9Waehi}N% zt|+_cvCYFlaa}oC5=ikm#&_o)kis>A?;l6^N#A+%03xhEnLGH%sB^tOrFC{WX&XTR z?b#AAw_A)SElbvNh-xo}Z*WXrKiDp~xOl@-j7`ao@-QGWX zF~@*Uh$+(k3lvVUKr_G^<~vdEwnLdz?_#i1<>R`06K6sjGhE<9`XmJfSE><^C|h%l zXpcB>zp?&N+y^i(dc$glI~mGi-L(NU9m-C)5)p(4JPGxwm*r%y;} z1_l5)0Bb*CrTh5yhk?ng)TU}0glj>M&W$3ispAV(k{bb4b-4FjQfLAvLW$jj0I(!0 z*3tDHVRaq(oQHr8TCxm7f1GYX&BUH*08BH98DCWA3j83vx|-8wrsAKA+k^KV_kn#3 zsHJViiWJc|F1t0nUhZd|{rxYx6SZo57Vm3PxRT-a)Z&dmy97HhpPL2lGOr@&>FKX> zMNoiQmHumEViyB5bs!M6fd_#pPj|Y^#A0Jgds#cbo-uy+1b90Sxg382dt$*HW4G5n z=-d70NzfD7gZ}`05;Asnl{8tv&I46=#ito&HrVXphJ&A1a^Id8326Rjz@Az7u<8Qf znMxDGe0crIX6ee#3;=U{F!v416QK9GHIb4z{#pX5b9-=c1{{{Z0M*KOp$A&)^Dm3v zy*%&sCXtX)R=roabUd8lfBjHK+!v|j9_@7yfeSCd(^=it3N?aoKxsZjCyKJV$1v$DP%DTz;Clz=Z$7tcqd%=`9M5LsHppV9}T5(KFaL`+yP%EcPR6(($+Sla0lZWU&RFIt&{3Xy8Az?O%b#;(UKGr^Nan z%nHixBAa{=0G!yHf>SualKh*h_sU~-(US)_XIEEG_@2&e6xBR`O-Ly9Q6F+)JO3A~ zS^*oq`^7}WzlCvW%BeM=R06;-~^v=ZU z$r%Ga*!rIJMA3E_c=ghZM;ZW=4M3jJ{EXhXW^q_y;0*c;bnF;2ne?c{#KP0#g4DC9 zM{U&O;x70mErXz=xG*{22nA}l4Tdu9MsIXL@W0_O&K12$?-6(a&wC7}mjawB{T4Wl zZt~vynq1YXiWIzn+X`c+Rb3}&Qg52`pX zp6j#if=X@T{6C+)chEE$bHL76Qv!$oLC(M53!nV+a<-=sJo&E(AN7oj)qNld%hiz= z>^J3VJ^G5P_NE3-sYf&WY*pC!T^@Z?VAU>!fLT(q%H7=^{Npt^GGM<9@;fo{6BxRw zuW(VJVci#t=Ziwqa z;{|q1^M$Snq?NoCVQ7+bDbhYAcRZW&*j?~PbC?Zq9oBBMTc=)ACUUsbzSj4{B#=+@ z^fz3Toj~huS3jF;1S@z%+|E&?**>rd2PbG;JlNO(dX|zpLu3yVGxJ~d4$oHPqFAsh z5=hOOtuW9V8lL^w=U6oOr10n!JX$Y&$Iza=$owfn4|LCr z673kWNQTj|c|50Hb{Ff;#f0kP4mj2uL0i7nuFzN#JLusw9O!0JXQ&SQ`3-u=VBujz z<`3P%!os7A6b#~fRb^A^TC|N41{$4;8P1OZ0V|^s3JPE`Q{&nUtYm>)3SD)NZB%+b z)Zb6^$bEssqQc_>7u2E@1l)cG>ICko^u?5YCG z+HA0^F$h{%4cIXPc>|Q&7~*fM{=b7K(TwK=b|! z7$^BdM>A{dewRgA(~j-v$M*vq833<;<%02!0o_$n6z7tza9(E(cq~xlSHX5?gXfjv z^|uL5Ci&^Gkt!J(D32RzpBe)k*e1ax1D6ZHzb?1sUJ0T$jXMiLQu8~0qaJWXFfZR8vLVUaXGT|A=HGJ+ZhQeEgEnRjU@y8^;-sp zFw?Mq{}mo!r)~%I$nkV6)-Ql}LE)9aYR(3mM>Iw>=8ZrFo+$2XSe>3!VXlST9yKol zK&uonJ~}*X(34J4sM#1)%wHb~Y$m{I9tX6DN6C7)$y|{^(4X6-_zne(xqV{?Iankl zkE|IMm1oao>6MR)?DUSqZJhn169^+o@Top9MV@ZWi>=l`eqszXAh7HOY=NKv6$MN5 z1)=QXld6m25sBCWw}g^!rUS`+t;i=qj##MRQU3}FY47isuH((I)`0KpyjkPqg9R%SuSR1&*9D zRaG~PfQG=wab1c3WB0Db8d0A@6>mG{4U0l-%i03OD@aSq}~a5i6zG1{l9ao>yI ze2(h-J129^xLCKollcPctNCKpRJGb}c`E|YT9)iLh~$z5zy@1Z4JXyJR;}Lu0jsrk zcXxxlJb*n8S?J}$rvOEl^U!z!?}w<{d2m2BGVVN)x$pRxVU$ zUUUc6jTZzwiR363u^*$LAQh)-tvDe(-=MYlGGLeAVZ9f12Lkp8zvSv9T%YZ%Tf*~F zNa2HeWYpYH(2j@mv(SKXt+p3f?H#r&Q0}hJBVu}9zvgn?WDCctH92JJ%mVDMKLD zSlqBpGuqmN59k31*kI?{@J^%*C4_5E_76u4Hpg{;oJ0Vdq@cL;)-68h4-}Gu4MtqZ zdF38HxBH7?#A^c+6P47}I5j@s)S`t;l2ovVV{H8BPU~^y|2|*x)(_{;;`Jiu;f3IA zU{DZnIn#1|T@x>M2D{jo-V@e*FkK43z(E~196;r;xGU%uf2=K_nUI6MJwZ+z!^Q7@ zmgE2AK+Asm^rz$`6dE4^Gzj2Pgn$p608FBI4`vHsjhc&eLM>kDWN+YvlbJ_yHldiC zns)lSIchxIJiVW(fQIvYP1TBJP_*kD989s&)x9nCCI(O+oPjVoDo+W}eR~9qWBzZh ztYY`SxU!E19;4Zw0btrYXx4*@1cZ;k&U5+zez5dMM0469gKE_S3AfX~iY1^eodxkeA*y@}H16mD%JXJTjn3#NCV>`oLtB()O- zDn+-B*(~pd0N*TpKu^BF6EM)4brt#nvkVsfCv#V5mjZ6Sl}`Ja7Dh&3z+=Z_(2fEc zJeS{UfK2dv5}^+gqCbCvYmuE~NCGIi_^}4_Kgz)?+cV8AXM}8*--a_p!Lq@_Z2dt^ z{`Ldr663k<6I9EfUrVhW4!)OIGCk7vF&+xfkH{#g zzU1->uY@AdW9^|}Yd@M0Z{NSK=E4_#=E>*E*I?#7aCEp*c;g295m?I1QeHMxE{55F z%|!&!H!||;2*zD$yb%0W8p!|qFD$KZ1tumE zMbF5mxH*0O%4D-`T&UIjs?n=KCEjeG5Vo3d(9{*R#R|?S23R;O^t{m7+*ZBw$SNoZ zzF5%sj-J4=I=OhBo}2rUVNZw2XTe9=c5n=z)xgGvK4GJ8P|z>K&ri~ZLNS1Z-+c*Y zL^ak#l2qnvmVI$?-`VEC+?0JR_cp(sGS}g*VFLRPH-1jgMl!w9GO}s_t^?mVTZmDU9-#14Utv z?fL=|_-o7`LHv_%2ju;`zlM<45&F!KK=G0{-#)!pfAR6%Yr3aoub$%~{{Dp&{Qvc1 zg_OgjOH#0gkYQLzYly{Y54EQc5kz zK(k|H+zq$sw*^t1Gn2y#n(@5a&W-Fa`th(#CcWsn7MR&mA38m0nac4MW*~ z;Zol5Ar|GPsf88TB#nG8NnRlUW5MoR6)^@qk#h1=$iATKx7w49*15SSdr7lKdw412 zUoO9RR&0xCgfHhyi?p6=>pbb|5^V8V^uhd$BWXuNFd+{%E5Cuj=G$NX3?*c;TlNH7 z{B4Z|$C|Bz_Z4WS*``y?W{d*rwW!U4v>_EXUFVjw3b9u}z$mfqaCqTk|Hgazj8(Pq zLg4(a4i7MPQ%(P^y{`_d>i^Q+goHFmgOp$C5(#M}l@e(rMWkCgr5h0yX=&;1Zlvqb z-QAt{bG|e4yYtL5Gk5OHfA_imgTUeJv-dfBt#`faeb=&=_8mZl1UzTZkvu$Ziua*0 z_Z!B$iF1J`U-Z`tsLZ*sAosI&txuaX58S+Nv62ffF&l47P_J=rB0^)>U}j|a6;BDh zah8@3mlbP^w%3zw*7qo@Z95~VS|g~O5FzZx{6XeQkA6b@|T})P5I%E2L{Ls*O zbv3G_;9g!{4(~Y=TBiat z0nSPFYP{p%<&EiE=WQYeQo!=Krvd`xor)Bl7q-hrl_dN%)dsyA)X4XQc}LGB5gi<+vk31q5a&jPH8=YO0lq7(jY zRE0wD6E1thbIkG7v=1ZT`N9BO%V;rByxhs*Idj3}!1oBtdVNL3PzbMBBdp5J)?|}G z4;3~vgy*!p_mYK(cf-BEzdtCXE(EZQf3Or^zkVq_9`SlQd&@oKEYTcQeWu0%BO@aN zO0Pr#r5(Du`nZ;SbYe6XR8&&-^<6`DFr(+KWn}jVE_bk-H@MH7e;(lS7U~3o8Ym5z@l(%~MQw1i%lGj#ay|F)q)*b4E&$0N*9bWeCYOJiU8k~h`mdACB zjbQ_;p7X(iFnBlq1l$)HzRS;~F~di=;8>(dm@bbNGJ5{}xkTjN>|uHfsgC9MZ{PHP z6(;XA!$&vi#$PaH4kQKV<*{hIdnYa}Exkz43Zww=SvGKsmuVH#qX+p+%iH{VMu51| zI68Yb|`yYcSaof1zL1uxTgsa`7^kpcD+E`g7)aL1z0ax|IE zA?){mjZq(y9GmkDODVb<`7!^8-!sM@LLT2nkDH}>ey}ooSUrGbWEFEA8^GiNgO(~= zRnO+{Sn854`HLkb&#D(!lfMg<=WV+a220TP>XqTvyPmb|#Fm;RG!z_r+`)*Qzuq9< zYd87_+Tz$SZ=obTp*QSXPX@Ocq`~KfFr%$=xFp*;SZ>UlAn1TUlBFOHj3wY6MSmBK zCVF15XJR$4y}QlWsQ2-GUR{HYnHiJM{S_6k8Rvob39v;iU=o3gi;G?B@zD_w*B~1H z#T^MQNp(xhOBS6&p18@0h1PSCHI0IVp;w@uO5Z~x9&8Ihd9`jq|S?XI` z7k)}2pug{6W{>pC&(D9|stWj@z|ReyRkp_gGY7fqg)N=aS=|`0(?lHTwXE#nVkZ?1 zJ3Dc5p=Pe#;(1NKy0$i^twG8Rhi%G9WW-!4m!@iFb{DYT0Iww|^qB6PcGxlVPE>SZ zrZPX1a-rv3(GC2z+heRND=Q3?C^E?(i5@+oK6?G+=;+91ap{4@+!6Q3z65j-l_6EV z)h{wnCThLdr6Qa)t?Ii2#?=NlsBbPt*!*gnLH=&2*ds=pSE%OwWhxk zXk!zE?a4xk*T$%DQZc`*T>Kx#tIJ&%WA?m9uhad@BXBXE$ z`RbDgQ)FZu$kyzd0U%RhM9ClnK7l2n68hX4z-+0kvrZ7&K2fK7RpvT6;pJO0b3P9+ zKY}=!g)pR1ykluGQHNJ3AM00FCkRaPi{-(EOZk@==G^kt_19+x`}@}m%d6r0jhEQ< z^}xJ^g&w1z`8gyKeS4#kS$#1YMwMevX!isk9TcegA3r`7Fnsge!ek+oM8r|>qg;GM zSg+j1=2lC0cTRW76a3&EvDTRF2A}e9?vL`xjJ$~@iw>&V+F|hfSxZZ;x-M@fGvH?- z|JKjKq9WYM$;qO!GL@^42&R$2V|jwfL+wNa#NlyvCNP@id0y&A9-h}Rs)xaQ!|k$< z6tXOwbx1+pugA&WfhAn^s#7}j0&~3IT3@c$?~Lx}5~ruyvq(>9bHdm6FyE-g^IGKC z{gIVup`Cy}?Jj5?OGun(FaO2yUqL_rIY=6P4Cgf%SeV|Pn+0vWc&nj;45*p%Lg`(E zjo}6%kordJ$!J|8BqSx9Gd$e>{smvxJdPKoz~`RDML~imsb+*kgo}30e0Thgh`u*4 zy++Ml)kSFGaJiGuV~u5LZ&uvawzx)JT0;IC;BmC4Dm$sYM9M5C-|lXY$Uyjb+*0lj z<^IPY?>{`vP4ilW?zZ;K1qHc>_E18dJ!(IF^?in|ywO?R3m^deeO=Qr$JNjCI#9QtqjVCj>N1 zYF~`{afd*?e~9QVny?bCuOlkrU&@DBdov^Y&KQ^)_{*@l0nMiVD6s%PpOyvskG;~v zq!2j-S#$|nWZQEB!KhBd5ELqc?QI^j=4{<>kS^5s0O*AT9`(J`dfy%<@gmb@*mV^Z) zKb^{Di{r!2-c-6KT^ON{b3u%WX6;CsRVo=^9!E{}kanBk;f+pw;CO8I0L)xsU}Y8m zpnuZwGtlF#D|>W#ow#Pll#TIFyXyYAUQJeioQ4&tO6v@89!k*MIR&57aDiv6^>& z2${_Gqd{W-$M1&rm({XZmI- zE5EBsEKeCYTJ~EAD&;D-zc2hHdexuO(C`@2UooHM{Pc-j_ff~a%%~SE2=8YbzsDB=mFuQ{Qom*!$H;Lk4h>-Z5CGH&Z(U9|0WFB}75l%Ne zlpM{FX4<{ps>sMZ%L%QB5I36{^+ac3V^BJ0f}o1NzM-^pjDwwdA_CoWpVD~By?KS! zkK9i+wUMW1CrB60N*ryM?P$)` z1PR&}oF;zcdqVN&vy-S%Cma~;C=OzwYClR&_b~z;lQ%_S18%tl`<8WJsGVQ9O{{1#SpNgX{H!?8w zd(q=zluR`{(AJM-0C`8uQv9<1g#pHnUQ`u8-tJ0x6uL!#c7HrmQ{i1ufKA)_7!i6K zZC`BP`hX;!?3Xf*G$2x!mNwlO*w`d(Z5dkzL`1=RyRk8cXsVbIGah^x%fQ4UrbP24 zDK4;rtwMF`w?*7lnIa+j`Ln^|cqHxG=hEcsAFJ@saL4JQIm})wR=Jh=EMut2$oETr zbQOL!a(vhxLa?zrk8POc*3>288blILnp0K~S0PDoP7UY*$7<8JDaMkg?ykju(;86CIl+nm&mPbxd=&R;0N{K_$^Q4(;0aYHyj9&># zqt2caQ}R!zRj2(`AT8szQCz~=oC@7|VV-H9;>#Pzd6qiY$9%ihFl@El+XxmlluW zCFv{Ioab#jl)XmFh*FL|#n}kMNgm-js_)Dt0%gThS4*!=840cPa)%4^zM5{0G^Du| zj8{$l{Qcn(;g6zd&-5k(NmD7^K8)E?FCqwt^Gv=wpc;Mxj5R%d^re=$*T zK)x2z;)DMobG@~*kn(j;chTxHu0%iwosG8o1!@hANFmyfv8V8xS%5eB{dCP6OsZ|{ zdr@8xCsMKs13i7G=}v>uhGGa7r^+Skr{5)?A&4p&FowyUEDDq%SOyD)gse!M(=Rb!|h>i23uzf3S_CRR4GQ}=9)IU8dL$jW$ty)s!=l=VZ;&a8Z=9j z1Y-#-oQ{?aXh7U1=UK|D>sc;H%WQ$xR9eM@K;PI4kbKw@2>dCcP!^Fp?}M z7II&b-yxH~gZ2M1n<7%3o*pc-rFgrXbrwf$Tg-T|)!GQF4$-nTv3w9Lk$RH1{J@wz z2;=paoQ3*gHOqV@wWrO|(pv&)`R3PheOLzj`k&iSV;MXgiPWjiB8a>tXlo<2h+&qp z;+2(8Wz`-W#8a#IONG$ZAFqjdQvEFJ0N`cJf;8jr+AXi^`sj{rw9QodwUkT^B|+ss!<~;xO`X4v2N2BwO7WuoN9@2VWl`gL`FH$R^OY~@?t{5lkI ziBS@c{|;gKA7a`6l>W>p+(ls+nZQUZHQ`kn8UOt-E$biW*VWxM?r6W&_HUu9gi5#+ zp7)E%_sCRLpY6Toha8p3zWrXnCS({*3rM_4)9N}~snm@m&8Su;wWJb0nNg6OJkjB> zI{Ylf%t~aY`>63*{sq5gzFKOa8Ga1Db=IhRsy6b(b{^L>ateuqjVI%eqs1?DP14Jt zQ28N8t{~)ByR!zf!Ake+=N&@J0L0MUQX{l2;S1KqN3=FdEe_qvl@~TP{1d*UWqsoY zfeBaY=S(1f2ZFfcmmICDz*EZW3(%#>?uT$iqI;awgqP)&DZGh1qE+Gl@OCTChP=Ji`Nj0~aJ+6k3B1ctW18s%Xt-FZ zQoM5SY5X(K@bLa9yFnj~&DQVqq|6>eO{2XKK(QJZ&D3T4A0j)^CyR=?{r5u)CeBnD zQrU!F2KKWK_T>`p-9`IUdA(f#@fESNdim3VWq6tDyXzpC4G>x-wBMxesX`DY)~Wu! zKDHaG{ij_RemyF`I4#27%xkf2M;?ynW6}o=@fx>k96W`>fXdZ5IdwvTwCjID&<3m$ z3;HFiC@u4(Y4r;#nQ86cuhYDYTg)sM#Ob`dkLf%1wn~gX=enJV@rnqLULN1)xw~Bs z#~Rcyx%7BTi;rkf5Fc?Q=ZI@cS}hXv%Oh*e`Gx}nXW7|0V#6i#AMhX~RMu91T~!8J zStnZT@5}1yXMrG%$)EZ|Tg~9aC3j9gfZu?@gj!kwUa3h<=H3J-n6{rY$~oB*hP90! zbUYpCo2N;AD!JR}0+J*{*MQo&*%tukXuKHjY7(UzD{M@Rg6Exd+yBsU4vvgSCX4mk zjYuR!2CCHh68(!7pt6uas$mSt$OvD1cyN`SdRAH@-Q{2B+N^&krAhPjg?Bwk&su4& zs3v_p^Ge(ysmIKmV-!z0PK4tewc?W;!Ks0HexbH+YBg zrF@aq$L_*rJkww)SKq_E_4HuasAdn3+6M80Pr4rq#l>Nc)cEYgIo8mz9GwxTau+H!w`Hxa|AzqA$tS=sjC!SVKYOiv9zE5)`M%5 zs-xb>-%+4WM--iib>l0#4w0(q9Y*;_s!5fS*+xK<*>(Yu^l&B->k6fcmZK|C(Jh!P z8-&KkbQ$XvV_ zChH)8#dIKY?7SrL>4=o1KW78AEPBtJW<(aFB6sz}S(2{SXZ`X6{y_t3ocbxOx( z#Er|N()Btv-ks6S5tHpM$w*R(>3U$4s|*a^e6j}uwz{?zFhXPeB_@WR+>!AHA6nR(tpx`JEUBBi6X??Y&S#CAu>v2|@wV4I){|kE z_bvqDftU{26LqLEVB)b@s0%p(&3)c^o7|BjP>+bHh;a|bL zx;W{8nU5b_yu#;q*a@@R+hYo6KfgFMl+X@FhQRnIsL#UU!}8vIV`NvZy8Z`~pazet zmbp2gOGs|5oc9Xs&67LXAE!dPMR}>GsF<-Tsn-}WG0kZ*J%)}SERo>>Yw&Ob9f#%q zS%D2O`UHO1rF{Z43Lc6mb=sk9Lusf9_S+mZB)|3%6A<`%y*C6its;T6vZcRYA>)*B zIv}p1wyf-taeqJ)I2T}3ka11$1I?eFDO4GDTk#}$Ljwbv*-o6t)XdBTpk0ttl!u>y zgQZ#(76LyQ+le5UiX05Okl!k9yJ5^6yp`VZxw#f|UrK3g?6=XRQBlDl?=<;%9=m(> zCvs*YNRNUg_*||YU7haI^MWNF6!!x7ECOE!0t4Rn`V~8WyFfd{S>|-r#%0s3VTf-4 zFO5qt*?&A!p`&`xUPi{*kCUKdY3I_ODIC=sG*}E~atXft{1!AZT}&ciK=JkKR|uk4 zxC;mBQ~3Ibs>=b^I==UO@87>aSZGH2@X-hn0@ma=YKzaxYE~)v-O)yjf-Nhy zt6PMaZZF=fy192(q}1%9crPuz?{)VeLX?gWb^gEyj>TcNW0HXWf-XK2Fvs9r{&FJq z0Q^6k+^;s0PvUt%%&ybc>K8~NU`wHp{6Z%q5kDAtnp=3HGfF?0a1_%oIzuWSnt{0%jeI6)m_LAFI|8fQC`&_VZnFl08aLz{ds= zOtRgMZ~{$SFG_Uy4hoB;IbmUqVv84$sG=T@@yq@uYj5lD<@WcSch`5X^KL(dvxN0n zmkcCw5$6hDLGfdjelc0}P*X)LYsKzNM4|9KKIqH+QH2UPTY+QMkhefAOV$o5Z2N3*n$^2N*0vMlDuIGUu zq9?Mkm2+3=(4EfcY~K75@&>(0_l7;$N!vGjKn5YX;m@&iVITmSL^+n%xdcz&ujZUb zef#DIHk~XkWrUJ|&KV0I&fYzeD`Ee~S5>2)C>oxdS;}|o>Yss^n@&IgwSmyb;@7+= zmC zfvJdtGg&v1Dc3GwUHE2dZR^MRfq|d|E#B419&5a3%LO`U5X8ET7w}OLg?t@;n;_tY z4Mr$_1_KdqP_MxJXtMjZj;2arJdXSMQc)4dnq4O#HT5NhfF~xr^}Wq&CHjpy$5set z>6_zveN!9mdxHv8nLrdo$~1rjA^4*9+|4#xH!}5Hn4T+YT(7QA)VPH1l$6(0R9Z~p zi=&_}xN9(g%bBh0Z0h{W!Ua==DeH`@>Bvn)Q&ZFClg$_Mn49OMprhaQ=g;TF#Kaj* zUm(4So92~vRH&E{bag$FFL1Y(pS-wn-xT)`>O!kN6c!fl>gn+fm*=Yf0;cNy5ID}u zyINfZEl{;R;=c4aBh|I3W&L(AFV#3KwW)3%C0!im<2Gv%d~4{x=W4)D!Cs(5cdGO zFd8U?yn!l!)@0P=`;_of2HwQ|wI?Pzi4W+R8|=oFGg%X$2Tmb@H7NKEx2V*#&$Rc} z96iN^Q5yM>ryFh`M?|n5Qr{s+&_?aV@X~P+fOM0Zk!I*y)|%pv1mkJO{<#$wEV;!_l@3VATyLq+Bwjy0N`92!%GUvcpV{PgvCS%F`7jpmF!EVKyW+l@|2Z4Yn)i^;d#ohSvOfu!d3S>FI$dvbCcxo|-6> zCQ8O;=YkVHZhd#ETpUc`J3QV?R(h)ya^vF;*KQ;Txe-D7py37lDAlEXTR+AttAnZEU`} z$FQEM3kG4-uRr}8CeY8 z1ArhzLANPaL^~YVc}|WFCD^GH!LYSu-*XX@A|ANIxUVyrmQ@I=-d&Kh3G~<~gpsMN zso=|?cC*ZFKw3FDI`ej#pR+Mp^uF(n#SnGnv1R3dsN-4%g44T2{I?cLM;TsEMyEjeHi*)|=jd%%-FALN3uo|fijd{cCb zDo4Vrn?anIJB?yAtrH8DL)`@4P`O?@(+UYu0^36r`TbsqQ}OAv^c_!vm@#uZ_h?4B+T=cKh?pf7{h^$=qbTpETK{m7B1%nM!S7)0TKwM|Z zn-NlkLCj%1ryYhx)_Ra;c8CerrWyYSdbQITRQ*eg7TBMjftYP8-3_xG*wEm^hY!md z?g=UBPxD`;Zr*B8VJUfKFpk*_$v~M|S*=-m$xI?fM%-R{p5$?UE%1wRSKDwogD|rgx+_bWN++E63n_fbY_{4i?R^qJ_p*mMrOfG_p4JeISUqO zAs1`=L+eycnfSXHN4pUql~Hj^7*&Z*&s+_~c(_$h^_`NQ@V@cUrQNLhM3qbQj9rdE z1bOP+Yx$lxPT{dNgL2SEnS0uuxzp$wMN9s^yl@apdR+~9P%d#=`hJsFIkN$SJi6T} zYYUs7!QRci{@MvCT(v~!MIi;$5JW6m4C+}=c-e98W4VZ%10$E38g4ZX))2uU7^KFV zE7|&~pYbv3yRoL0+qM@VJW>T>zjjm0UI3vT?S&Ij1Jcch?b%8%s)%GhHeMZ|H#)*N zGB17ri|4aKq%G8rI{kwxGf=`~HRne1wK!o#bAnWS?5Rp?_U*fd)T1ftBjbUrAW8MgSpH= z4ns;BOG<*zfo$m80alga!Y7;CcHx59|ND6(i0uG%txnl(Y~c0&Sj_0x((mkyfb2cuaDHMT(dfyZ_$(8OPrI6INkm7rI7#E2k z;}$|n@EoPt>p{;CI*@la4h+H`Uxv&ab%v7ym8i9Q^<6HITq@^B#F<5fQSm-DH8mY( za=N^{aNQ*q%0-Va`yb%v)A2_2n@}|b6i9ebah)SWzTWsc~>0}nrf&8 zi{so%kK$@N`D7X%^0CiC>FwLF)%}8|zgUyO*RC_0Yk`ZC|I$XCC?wgzD^)oh~R*lfl* ztpg$+k9u_AJvLciLB9WdXSWSkdjVHf1W-?sa32xMW!vzicHgXePM?!!%E#s$X;#pF zkBqhhh&=mK0;BS*XK&9yVZ~!0WUXYApNu`r3_?y#m6w zdESe9nW`H)?YA#Z92%;Qss4RcYpU?RwZUYd2r7ZcfPs(C2^?+oR^i%+6@%!_D;?JLHK-{U`@=?jVS5jahGTaQQ9LjQ{f+HrLnGPv3w9SVh=TAiB zrR)VRuh~Idf2b6tZp(hg=IXfr8SE})Y7BBP^|EBh;Y$5Y|070^>@x^wlAzKBVr0K2 zgVyhC$E$ekt$q1)Jf8Kh7M+dC`Jv4Q-Q!E+i;ZYlSO1>?ps;OeKm$8*IBjQ~!O9JB z0~dsK$K4{6=64tRt4zJu1MxuK=aIjL3Us(q;S{RtN9f()j^(B_=KiPaqkO2Fnp{W~ zfPxuyy*Y9{kNfsJQ>U%Nbj}v1Msa|wCF9?54ZSI`*0XK4sw>3zO<`wHDFosBa}Nu2){2>`W>zJ_E1uaLmUaq!5qq z>Sm*TfVu+rik%P_yBgC#4k=o_59 zG+$WrxD#ZM5@2}2Plh!Ym~5}H^0_bIs(GAzp1Hm2{ss$k`IfFFza8)^3IascM4bc1 z(b2Jznp(iDo2M8s=nrPfw~k)_mZOc*Z|%SW#c}hnr0fT7=C=2ouakw|z`2OL`Krf& zRspzZ8ASQKs|_SRzOpZ~hRSUN<2VIultr}&x>TT2_Lq6`^_tO(x5Q2;0<6G*SNk_b zhVgm*U7g9EZ;fJsk%@$hA5C^nH{@`+1BhH~ZN8b$)^N}1++iyu7HEal)o4+kW=kSM zL~BGBn=#3@pbV3Fg1@r5zPu3Cs`^+CwqkOSyskHleE2I^0GfdQDyg~es`fjM11hpXpf9*3&mr*N_0TLR-NJ;O!riNn~0W){cF zqj$30jo~%u6t{Wt+VQ}`SUEx6^;w7Y_1XK)rHqHk&wc<`ZL^Qd@!=`&yMv2A(XQq8 ztEjnfnQ?WppLFDh-CT`GxOgu)?~VkpWiNrlp5)GsI#VIZN8x*t24YiD$}oM3I0}wZ zHl?9Y2ZKBATb=xft5I462yFYbxIS}puiQm-K06EujHJ(F$L zfzrDKapUs6A$Td~rZrS|v_hDV$W*tmAj+ zS}M`7@BlrM9NT%(pSWy>iP6KuqZ-Kw7D)9=I`Z+s$wAYufYU*r z)4cwWPvz(oijK~#S@H@@MO2q?wLCi67(fB&6dMv3Z#C1iux23iGB(RS;>3c0t4|AE zM6?xQ;?eT}E)k=(`pc(|wnj(ktR65kH!l1z@wWO<74L7C%M9 zLm#uBrzFCQdiL*_d``7de=(hkmWk<<)0XL|`~J>Wa)WZ-#)w5t+UpiR%U5g^e%M&5 z6$>7dllB|C6`m}Z4W;O~xe2B31hou>LbgU#?3cTer8z&nFw!89jPivI> z;&xtCvkQlclfrAs zaQ{7Ud8`DCpK#Y4xl(gw_BEYRRnQ4AV}$-->-b?^xs+I`{(E$-+kpgB4iOIIyw{pRON!N6x1f} z4!|a5Q0z8LABE?o$pJ~arclsPa>ywIP{P}S4KF~_4LJXHaL0n3U@V1%N-pl#XS={R z7B1kFvCG2D+#1}dNNqD=12FA3c_;3zIBh3&Mdc(~b(LC$XTg4Q+viZvwp-mvcMqS- z)`#yoAG@_{+|ieH6TREgCEDg9+9%ML!BSEc!^FUMoc9aS-1m-j-wzlNl#LYvQ}?qv z=NiIaSob%_m^XT71!fIbfYL-sm;Q;(3YwpE0N9L#oz@Z25&MP9?wB!`5bix|L};k8 z-F^x!SZPy$fvX%w!ygiGgxII80fTQRX?|CGBvkE59Q@lge66-AO**{gD8sr3>s_5i zur{k7kL9#J;H{HS#Vhd5MRa^UJu+awyF;I`12)=<^!v6T=GnbSp7yCQXg3Vzs4{EU zeZm9K3|_`nU&4Di?LFx|WY741O;s@GN^|}j@|s3HIju$uPd7=oio%mrSvNim(5IMG z{Ft+~4xJeXJ%Dop$OmKxpZJH|Qb97D`N;@B$jLa$x{HVd8_?L<*(VjH)i>)4{{sqI z%gR&I;jvbQMKFyoaJ+p~Oyc*C2|(@ci;0U10or|^C_3E$;Ku>g41=YUi%^IXowO>c zda+1_*qtvfXcC1zoIOx4AXKug`!5mHqxsuUXw4*yy+dkLz)3^mNI8yMvB~WDS-5zl zG`usNoziFfTU&x*&Zfv`_YG9yhye?rfum6?)sUy>V%-@(X5BWlAX2=OxXM?x4{23e z>143NU}?W6_Tw*014*l0TnJrN)wG#G%L==IQX8oLg0{!gY{973yn8!J2%b2#BdWpx zC3xX{|1Kyv$gFS(S>KYc%mxe?6JG1{P&SZG;D)&zkS~N*&TB@@pWOw33!=6;ou|q5 zF7NuK7MGL6f^1MoNXs;+R{E(bdQOcsbR(BKEd?G`lol1eIok)k9)f7Wf&=hCAMD^) z*yW>vy9CZ0Bzd@Tc6oi-F)fm2$Jx1ZA@1$Nl73|cLCDWuNrA84%kS{gY#CZK%C~zY3WsdoZIVH0>Zn> z^0R(+z|eTHRLY)SZmjq^H!J&XWXt3v>7Do;4xlQ*YPpDv&=smd6>wPZ9rQvc|F|MJ z%b3b}x*3oZl;n%8BuR@0?l?0Y=|vED@gCzvM2cw7E?DA+w!{0toxYJNzM&W;_IBUK zeBNZJA>(CBrwJpefWClaev2YtWI-DPG=&l9q<=RGxCjXeJufX*BC}d82WoeTxbYRF zqKXza?WP15drlq`%sRpEjWgO*;M6vzv#isYAxVj&xEtV>P|`u)1B~2nivOc!^ncJA o|L^-$|NlY%d;Z@4m#^EchzwH4!EtN}3R7xa8x?7}6kZzFf4rv5Ik&^B%k&^C^ZloJTy1Q!@|M!}i zb6xM8Z)eWo3nH6mKXKn{{c3GLnRg;+E$fRQR9G?7=CVvOMT<_?8MIeX~VuJkgALBQs9pxV@J#UyJs>QfNl3Ivy zg!4G}hhHu3hK8<=jt=w47)$HJYQH2uvDbbmF1XJfgali>Fp=NKCLd%(ZDZ>-HPUX# z4%hZ^B)()io^diXIG*NmG&nYqOycFa&3_-6C0%6#>5dn1I8F!xg!<-SitJvurX8y_$HxT_OmANY(VRju42Iwl5bXKk4J zXnR)L$jGR$oGkd$C#1u*;WU+EgK#=6LUVI-W6OfKK6leIGvTtl;kUtrJP*ZWPK=)7 z;nCYHh?)%j2(eVLwY5dXeD=AvmWRt>gZRY@{?*N~$w?-wzi%!sF77_E@RKvSXVv%_ zJ>WT8P-g_SuAUxgalYAj5jz*x{PuQVqYuXEX89~V14D{Zfo980fB$}8p^4gFymp_6`(p!L{Y7I0wUSL9QH(LIaBKl9G}?;I=*VL&nC&)~t7zvaw;z&d!EA0e|#HRP+uZAt5O_ zxonOi&FV=qv8&laZQr+|8Be6!c6&`_aW^S1w4av(vprQZlk9Vrr)yYdu0DB9ERw?}D2FZ%*;z z1rj{;?(S}SHZ~EGkmP~_IysU1yuwQP>c3lCeWm#>nP-d2EoT*f9!Eu7Ah>yWFbH&w zsRn-2nVOoSViR^xS36cZZYSC~@rNd*mdQVO@POaS>Q}e6g{cDd>&_cgYo_}k^Re~*0yLk zzJ=G&kN3CL)YK4}(n++%TMHdw>NOwVFVR|knCz5xcIJeAkB5gRQ*NQ5T4p9@WknB* zz{tcz$He4YM8uP`vomh@i)c?z#BKyTf8IxDXV|F%>mzxU&W9#-Yz%u6?kbKRu(mYQ zts{{GLr?hSd3b7XP2Zuqr=g+oQz1t+Sa4}N>s`}@c7u9o0%C6r;_ow9Hg7CvocyH!YTMBB@tau?s16(5x$_J6052)2#gKD z=k-eQ{*s)QmL?mw_O`#We{e9(BB9E4r0%wx%W(=6zl{3{JB3t*gxZnm>7?p?@dhV< zKAcAKSg)lYTrU|c-R&who{nWC*H8DLprDwaUvH|reLn7}&DZn=OSj)k$i_v>C!4x& zF-PfSEzS@2;IkpiH(V4H0f7PN_wFvN?CN%Fm3UGs73@sptyiwC4L}bOp#6B!~-{9|J@nLmWz6Eus zvBk@MyKPBoCr5E&;+siToc0@^yDR;qzbCBNCy zi`jT6S|pfg&S}{paWQ|oqSxOOu{NyWnjMQPB_%acYOiw@?}WIxS|++_(x%f|Y?t2z zN#^{mwdf6oR@7^S*Y`$VN5_pXMb=-Fa&oFhXvn(wqWT_e4aenqSO`f=2a`#7{M!wq z$RLQ^L89Iz{QGA4(^TzpOG?uhE29zh50$skuo3ijJNK8mlhpoha+Dflyn$i>i%dRS zJwth|4$GzIlK>hL9t)hZP2h8u*4~lGtiHtEzjFer!q=&8Y1XBy zSK8PajVAK<-tHeA?Ni|8=4k9XForIJ${2ME)-PTY{o!ePzUPen!gHpxD zWEYLJG?aW6)1hR?KFt!#QB8~7Y-8hiF2~40!@ixVZ4OjaUuJlt86KA>CruiZoMefJ z$x{2qsqT0;v?C__y~nw^xi%5#_qy@vaOHyk#&;`Z`wfWb0oe%D`Z_F)8 za*i7t8U3=`l_ep0`9rx-C;t%OpDW*?OHcxPkiCXptBd{+~V^^*>NO2p)hPocB^vOi~yWj5)CUF8JZ z0g>dor`63{#~Xmh6Z-wnpKkjI-no;G`HBtO56Sy)jM#n9MKr(Lb z_`J#TemH}x@l)*Mt=TN`#aDuY!aFOwFMAXDzKrtFIoqxG;y$V;1&DihWaRT_-@U(c zx3LH~y8og0!-7kf41lI2nQ(P`d8+reO!+$v5)v<~`qkcTwJYtT02SBM7G#DXm2ct~ z50zo1e-Q8ujg9@b{#2<_zsSP<9ucehY8>{rlan*iYfA-M$0C}aRiF6z5kvVJT(b^w zrkCetv#tSN4yV)%)mOT3-{}ZrHbO zsKAvCvE!^}<$1}%az;g>gZ`WPs|u~!--QAqyA|$XEf_ct zo<8X~P#N@-{(imko_{F!{cRo|9+ET?^n3SShbnJP)izPUGb=l%p{>?vULPS~&DFqe zsIPWl{CFZ$<+$m)jEOx}Fw-!({>d&{ujOY1qrkJLPoH+Hm3Z1(EU!)#K4QyPUmhxa zq+V%-9+glHVB^Dh=OR9@b9#G_Uvkw$X-}$bs)Lo8+wC<^L-%`P;^Vt}r>hYw{ds6q z+1V&Fit_T0q2AtVsJuoXbaF%InO%v`4>0v7<8!hv{V!4}gQ zwF9ZCX=yJ5X*ieao8`uo6${kK+yo`m)Z$>D_7_NNt)2<(Lz6z;)!Bd&w@N7V>$rK8Cz~d*=J2QuT9xrufes zO-x?Bc<}`He%{SvXG98?u9pk4iHQ=J@0m0;3f2LdVqt0s=y5ZSAbW zIUL4U*VbfD!#ZmMzY=qDid)3wrbi`w`GSTJK*elrZ>JnRL!YPkYrT#`MRkpdUZG)k zTl;%46EuU$wVR?gPa$n}-fPb3xIxMm=|xZ9j-M(jPFtnC5Lh@dQlwC!370sjTDr4) z_~O-C{k&`MCO#rfI3OL!#lldP{qwbr@BOlf%8qPgQ8*KF#;9)S$76? z6o=Kx_wKll*VS=Ex6#-QBc;VU%6lGVz3b#=if(~g2wiV?_%mHb(u9x-8<%-rw?Ir} zWTNG`*PoGIGd}8m1Kgzh!EJeJ+-_&#^eAf+47X{|H_gl!^Vyt^ z&EwS)69@EZe_i``qm5}HBU2K5VN6YBba5X~%6c87TvE#9GNR?d z^8WW(w{2MBrpeOprZ0#gC95<6H3@$MsZFPg69(S8IufMF&`@d5ZCc}m3C<7t`Ypc& z&|+BiUoGZ!KElImFMQONt(tL{My&*yn1$u|MB$yS;kD?zuvEGSApiHR>Gz&cD~6x@ zY0BFdcb&y*N=gO{*e@6l{3sM(w5*ub9*G~XxpU_Yl&GHyKV@cqy4KxZS8=Sc?ff=7 zrM~OE%u(yKFZ`?v^Z5DQu9lV-s%ZoFhmRhiyCpbayiE{b*0fZdi;DICPU03K=HF)%$ z>GD*|IuGfKi|)#?Rp%BM@Eo{DTaL$-bASDKj>DzK^;4;Uw)ox5Vkn8byL-T?4*u%u zYVN5%iw38CWTn|AQ!)`Cs8`d37mj|o1%Imt_VnEHESE~2mKf)q;-Bf z-|K)@O(E0p437zK&eOwjv)Rd$>3Xa4 zVoBuKf=8Sw_g3~Xt)DaB-jdK8ghEcchXMV|m)x=MM^dyw??$-@4AzhAi?Hj61Xlr1MxwGk%GJJ&nSrL3aTpX`1+qFm)Z09KTn z7Cs>HXW*MqqAH82_3{>hCJO4m72VAF(zwW58TU= zsf#&b0p@s7dT4nyQx;KzZ~5jLmrnWD#}|k&a`&+Hyw1SM~wB?)p~QO>O3o<-^lm~_^$D})YL4ToQvjXJ@i781xY@f z{)|8b5b*f!DK7f6;P4m9)*_=CO;%yDva%whq3If$`g?n|aq=QZ@MU)|X|XX}<)Ghy z<#Vi!EQKz`m9>?>*NsU`%e~OsJO6(2#$!<59bF6`PE&I%vzYDdQ6se594E*sGZ&MT zT&RhQ>z@Ai^=r9!xv_~!r?h_*{Z$uTG>ai?mb!HRFMff>+0V8c&DK8lthp+E6?ARI zKnf~cDh5+D&_EB`0bs>ZzCZL+#s8JUtDF)K4Ht(jeg8;cqx*Zq5?0(VVRML zI6ORj%Bn|MpR3vO>qXPu%bwtYks=|9cZ58@BkRkoR@y%h^0<>~j5Zdc2%ur7z%CKm zJEV}1kZ>@Y?%j)^W?yv{=k%SZlruDtO6mY4H&$}$0a#urs#hc2qI}*kNn*0rZjlkd zEcAn~?_UZJ0QhS4I7LxaEyBg_+1TW$*(Rc~^@l$0?jQFhJdj&x~()S@D;Z$D2raJj;tufOo(tv&zceyCb`2zdL$+#HC9GBcgx8CnQBlWmFD*4Eaa zeZHjSqzQo1)Pnu5jzYW^?Sz4eo<4bxqQxaUA|to5^1xKf=gAr8W8Ig!(AI4)wVQ@b zW3*o6=w_X8^$80L%ezQBv%qN#4}bSPX!L@L|&Ix;0Y_MtA!tW zI3rpgqs+P8$O}=&FD--cxxPU|J2^dnpRGd%WXZ?&8VS}`PD#_F&m=GYON0pcAJpIf zqZ);{xR}@r78;s9Mu4#C>FMDzg4^Y|NJ#iR?ztsRlnke}th{^uOR|9I{YE z{fWsf00V#j{6q=LQ~Q&nWvN)8CZH#;CuXK;taf!3_KGFv0Y3g~jiaMYwYpP_he@2Q zX&(lKU#pxw0=mt3=<4c*$Kt>o7{`*KIgi?{K_46)9sMwnhlDY7XJ_X)vlf@`;&i@` zMhGXE@!J{Rk5sij3-xOEJoz$>sgZmwk%lhM0jxCTaM4=C#;)X`(%=5Q((X__(G<25L@>T!I@z$hT`sC}iBk{M!tu-GuQDd2nWnWF=+jDocxy<=$T-` zMCqsQg>{GBTY=A*7h0tpf$@lYpJ5{I+`HF2Jx>m@P>GclGzL^p2_@R%)8JXZfN$yc zIU^;uCSS@TBkkfqU!1DiM1K=EVoqslL94O6y!>T3VRB`4Z2-y_DDP2*E>5NP+gEOh z+-{N)uM|4k+hso1U=#%dPgZwzoC0l>QTOwoQ6{f?yqFUe@Qe)=6Z6!3c{q|gKTAVQR5aN#sgAL$si{d!N-D$4 z9%Z#?Z!zzNHFtExShE>VeSRKQkdk*fYuK?qngU9Z$X1!GtSlbe2kvQ?-e^>e+P|2f&+d}^MY%*hTJ}B1L|j~6W;CJK z)zzgNJ`c75irbLleIsmj3{tRT6N<{n+(#JpCg?AW_1Cyx#(oK|Ssf^T9!$iiIHsv- zPQYsu%`o4#^NRj^v0)#h^M$fcTQ%`H2>i_z==1ut)&;W_y->~exlx^3;x*hiZ(kHS zKj~7Wr66aGOlu2f0Lr*3(-!Y!3rja-Yx39omldvujC5LcIt|)}v>KJKi)(Lx!D2k} zFN|qhpW@)%zTn`aITzd7l|4GlUHQ*_ce}aoxoFV|q`Uysw$n`_UIAwfD=A?nd6_m= zvdi{UG5c0S9GfM($L~OBO?yt~ebMFGy!`z9^0~?(&$rlCrm~qv7HyBO_Drd>${##< zeXWl&c|8*pnYppdKZ1$bV^&MWqoIKa4GZgcJHFoV5_o%Jx;}eRY%Y@6rrrIcKj10L zGf$A7i*yd@*h}q0^S4LK>6o&55R5LVwz%E;rvv)1rqSM{`39a?U#Y(%;Q750k|ruC zNqS&U2~<>eLRd$K#CEAqx23PkXt*fi;AF#Lys5c>yhwZZEdT~-CKngP>rU03<&k>j zS{sG@qdim8)o=P{%GIAn@)$>XKAw02q~7C3{kfs*zChqzqm#&b_{DXyo0fwkX7>8R z`;kbH++=SM+?6Go_&%m2!!Zw&q@0>G@7u+heaLSl)ci4U>HZF7(tJNX)4J-qJCdg& zGC5-I*=@ZLFUCl%si4_M?4rKUg(XMsQDAdU6!vf(=^f}JrO$^l9K5TB%$0+y9k+}0 z_lcltq-A8Z1Q-v3zT61<4dAKeD{r*s)|Ok^AmwNEaoH?RC?I+h_@sd^FIrI4m)WRR zyVK~31V;3EA$jG%2*mi---0|3CjANdOv$)cwn{@lanG)?Ho10Ac6Gr= zOz#53@cObIuyB7rLy6ll>Mf(?p&&5IF0^W7@cP2Cq;~-iz11PXrPEmWm*Ky%wq~<^ z#dC3y7#1G=^)f3-yek+e%Q%xk_LSnA1`LqJjpt5gc`*r@*=Oe!9-l`?)#xZjfMk$l ze-Z#9XeTJaU;X{(m&qg+$@x4Jr(Hy^wV=z!B1Czt3WZWyXHj9x)$Hv~eF~c;7 z9zF7gCK5aD{NtvmM--EAlB;gjAvL#2ASxD}Bn&FOy>EljWV>I)Xss7$`*TK-8wUr+ zNPnH`Ii(Rrb>o(! z%rSstiS?$3c42;`<+Y4XH|5SbeS_vo@ zAWKHHUO`QFC@W(`r)QxF6yl?4&3ubeckNIlDVwcXTh+}9PB)SsVFtSM@t9Pl&Ei6< zN{Sce72SnjU|>WY`%99S=pUbYO8MNiSw|>Gl?#J_Blf7i<1qDTe}7)#FE#1zF5c5; z;>UcHq|xMo&vJ%FKtaEC`!;}>6p$_u$ThCn^!Z*JX}#49BSR(f#t9&JCtDG-Cq>(K z7F@2Z7~QDWO2LT-YyDyH6HnF_BnSR03*Z}o*BXP0xiXxVC4R07Qqj$EgMuRK@-^#1 zJ!<5gc&I~1t?yu=Q`wyp6&?TMH=@bwrYGcf6$PJ;u-wA>vekZI@X7_h1C6q~yK9%!@Z*8N=0qOB@>6)>LRZk{1#=y*G;Ed+*t6DM1bekehl5xOOL( zq`)!=1KBRK=Q<5|ul!XyXYBL6VdLTfS9iOiWB>78VA1tKL1?3>*E4GK(hg zEy4*4az%dG$Sxk{ifXo{P)=Nbuf;|GRioepnr2^m$E<8Mzs5};|9u;6(fOpvKBrp* zSyk^jAGMKMXYAhP#uP-Vnh%dmb%)~lkw*N&z@{a~%nJzri+GH@Y z`ncxDXa!P#e@s+BY;5dncw93zZUS;>E)yk=|Ne$Fu`@fq0o(rxAKm;>!X&f#6;+QK zr;f%*#mNftIZkq~Uk@5buk=bnc z16^T;cBk*%(~b%{krV|-;Juy97Q{s}xZu!Clr9eZ3Yh^RrcSC+=SgjYW0hnJYGnV32*B+WVU&B(adM zltH5ab^*wvX;uM}D)9Wrh6|cjALRo#30sNA>+b2+qmA1K3Ci2o*LUhtTuO?JmKKYN ziK%ke)Wo=BQ(ss_BrPv3%rqhO=y7R8NC-a^AA`)!?O<-FEnU@Tp%v^tO;kTyb8XIz zjhmaBwaxTMkEsy)`aEVt1djq^vY*nPAK9#xP)}Y@yefBnUz_-Z;7h7|y({HR4)PCC zXu@DlOD6Gzq1Y}<5KW%k*O&Gz-P{o8!cPhBR-;dX+=K4*Y8I&KjJ8LTnXbn?ZqCP4 zn}3GHv$@fJ{4^acDE_#r(;7s0&QHPDUW0Euo|@5E?e66qebB>ZHe2ZJ;c(^eSI7`n zpYWQg>~(kmb}AaU!!r0Y{&B?MC1>#e&#YnIcI0TcAg|Eag1>Gt`!5cs`|xVr&RP2y zRc4}2@x|xksZuTWBkp{2`;Jb3j*rsWt0XgaN^+NTSs)^I_=jxqvl~Zu9qpb&rg)D@ zGex^rlAMY7-QuNga_-4sjio21{7bg%;5lfyvhW*>gEsVYD3?4;ecO4uWwqErTnbrX zYWX!i{dXW%bEjLl!TYlK`w`(wuB2~&!(09$zRRU0$iM7rbh^bhORG^AZkiBWfL+eb zH2X{Fl-c0Ja@Mcn(k6h`5L&Q{sTNr}j&*Z&P4C*``}hVZ!Jqzqs*k^%WESHq6L~OY zOn9oXt+Ae@AV2&IAo1hHg5SY*ax$^Q#rbRj83h@cb?;`)fnh4Kt-BYXLz{)M_c2L_ zio)O?iUbiXwil)i%pP~e(&?-pnaA65(H+|y0jc43JCZbrscw^6?R#8{~ z5R=S~`?O}4uW#XhdirtUmubP7*JIDoJN zRA4X;8l2kSOwm?|jp_$0#LS0|UR0O-JLov0Fg0RwgPjfEl91UK2~W@AI|CF}B78n;uTQt*A*+=P`k2{toz&TH62IU++q#GPx=PGn{6Pop+z*kw zI^rTeo+5bLL48D+4CsN`><;j+1EL^(U^y<9x-YL1Q%eOmy4u+%WhPQ6FJ00Zn6a*j4kWc}sVm6Oxuf$MUM z@mHhqBplh!uFr-F`XWq~#H1wV_aeGVtjr*sgtR$X+O|H!L&)PK30R(T6ZJO^ zE-1hpRx1dCiE=c?HgzH%XVO~NKFga6fkzePwV~Eq$@Mu@iKHHN-|0)=4O^zus!ewp z&1dIiFLGVHTX$tc0xMXh+5}VP*C}?Va{aZv~Ud^O^iM6y4#kiU|n%!Oz5*A`K-YbviaN?Xj z6%P;8=*Oq^;h6EcG#5+R5hq3BWVY<3GgX8LW#fX_tnA2CytDm!k?k=ppvs6VJLeBe zd@}l1XhQgLT=cd_uR%O}3l?-?QBkKtCNYBnW)-#_Vf&HCjivp_7mJYOxQ!zs;d&mT zT02|E$O3N#5Wh-($>4eaY=cM@ZWgQgcIkZgNY7FH-cv+jZ#=*GA?6@qTelq3}D9YVNI!COs`STx8fZ_^oSaGKh2S*q2Nd zD=HFm%7<8@iIs-d22$gVP#=Ge4Qa!QhBlGJrJmRuFL>3p>^n!2keNFEXuejO#U`f@ zC%F%gVV`T_9Jn8r&sq0i6{KG;^(9DyKT$d7{_;QfnWvsZ{Vo#`y60%E%iZlxjFv3H zhsi*cKfBd9xORwltafc&((}?)b<%y}P#&)x3 z$S}@yL6B=3gW*e8o0NIoU5Yy>FP5xMEBpxm6X`nmZ;9IfU7D)%_9JZ|lY<7`|A1vz zj*wAMFq!tM6FR%#jvw9f_5z(#J)|@%H#!;*i;(kmvE)OdK8vW@H%rzKafzCybs3*8 ziqfTccOMUrviRLYBCUVc7>!>xyhS~Olep)CX*?EHm)-Ztu?e}GM~|JT1T(9&6bt71 z=i6*XTbf&o9IxGD^wD?GFRE>EzdPYyO;=**>b}g)%L{21i{^AAFW;UD$(Q&lO?l*Y z|8uaPgE3k%Gv>#=1*%fhYc`HUzp#Ay990&je#jy{!odkjNT7L=n+ICh-;Tj7preh~ zEf}yu#NY~Nf(aiyJBw8O#w6!UvlneRkWi6^0Kz`*>whWbY?d!cqPaX? zKrUzj06rpDvpUH8OVIr%1U-FSN;X}CaucnfJdK}BT0&BEcX=capVQ`XyQF*Za&Ob+ zl2mGHYBZC_r-OkDb3tU=C7SPQ*u)?SA^3m)29hphBgx3f2-t`wv<#V_z>S{gjfe=E zLv_Xd=g+_R`7uBMDb1xkAC4^1b#h++_h^&r;;McY0@%$HRov&;_<9!=g@}uij}NM< zs<`)efA`HM&9df-0BP{WT(dnGvyL5~l$eZV*hIT&+zVmi_+0Lx?rzRu(cyxSPl8^l zsJgW_YzjS$xX&5EQ|-7sarpcm;Yxsco+=727WCTI&dzUOfMOBwHm0KN-<^si{!#r< z%oCK`3XO`-+xyEP=r5=^tcD8NM6Iu^{3(-q4)9R2t&gv1vr)+X-2OI~<7Q;!uE(wy z90rH>3f;3gU2x`eJ<=Nq2@H+t?itxP4H71k<6?Bu=BC3s6GK#tlU=V&jkHBCs^c(( zeSM>2BR`CPi)e0XnX}*KP2j!eo^=*l1siu49UTONu99pyz@B70JQ^9SOWkTR3)bjw z-@{E!F$jESXS6N<_XCN-W0za^u&|bb`K~ifqu#M|9g9epYe$(qU0uCd2N5}nkY^Sg z%#@;MVu^6thwIQ*%fXp-y^OGn$;>2&)&#b*SQI$dA@T9KR%$A`W*jJ}D249xmZ0H; z?Gnb>Swrum~ z5#<>x0>byj)nsiLH8nLac9&-*@%YNd!n6y6k*YK*1V?ETtc+%A8an7CN=+1?#VqyJ zUu8-x_g0RK=9`OHiQdVk$__6tdMl##oR9BXeQ|9hyGf(K1%gnwtab-_u8o&92{;*ak2$<;q#=AL`z+*&Nk8+uSZa^?KO#M0W8mr>H4H9dy{2VrQU(i z?fQh~8Xtdp8adyS&&Xf^zEa|V=S=R-@oAOG@Ft6#A4FSh@UG8s67%^`mUF2|z|&(C zPEJnd;&KXda^cl6HFnNl7MH@pL3r<$-x27KfZNLGc=US2e5^g6hZf|4_r=0ebqNQh zQ)S?*;_;Xun~vnS^`~$k(prO>x;N?*w|+)+fdi6f=L)B9G*!WnrQY}W+~FqD%lOUq zHf%%62nkv-S8iBbr;+~t{!LI&GRne2Lt)kM%gG&L*+E%>b22iezS; z&1ASJ>BpH$DI=phi?6%-i-fw=_q`tL*M4mm<>t0{`1FYnsDwd11TfSS@q}% z0ifF_R%Tn@so&`z3k|!~fw?pjOtd?UtCbotU!xb|xRnp`|G_vDB**k1ofkmFL_2%= znD-u$0`?AU(Ce)UDyD7U8hxR~#uk4_#8NATc2#nNS_eU!*Xl)g+E{6<$E%erTr6j5 zQm(ZP6)%cH+oThJnQT5o#Uc=tmzPhpeq1t>Q0=%fRg1ypaMcCEcCKpiH_glQoxR~M zoovVBL|pjw2VjESppkN>W21uo3vF{%SoDB>Nn2RlGZD}K>aTShEZ(y!Q zMMI~4*OM*W1ztz!+q$EP-A-B9;E0E$iHJ%`MP%QMb^!D^nca@NNzX$2)f-6ywHe~P z|J(-?dOR-P$;*c~j%KVID<$%VxoK3pOf_F-y5zIEC7mywx_frN@Os%6v{ygNc0;d0 zY1*Iius`@s+5i&d?sWL}oqKm154(-4jy8Jd+k!LJ-CW%&A=!YK39doM#EhtZ-4%Oi z`jp-7zJ$BxTjh`JU$BT$C4%!I3_(U?`)>#xGNiBB2uBC=?>%Fu9K9gei&O%5GwUP> zZv{?-zZA;2lMJ=|56|F&;6_|a{&j@{O#-?;F39o97&w93R%&kBSCM5>8{gL3{^vU= z&M9DM4d{cR$?be`hf9qs;z%gMEy&+r_xC@c?j$a33=9dMbCk+H4Z&u$ts04UK+K#D z77Dw$hoA``*l+bgVwN$ir~jqhYQMsgedXL}pk(X?O<2~uxyWUje~%tMuA^1Tz48GL ztf#{X*+VoeqEMAGcp2E@e0|4F>%T@1h&BSc>S{?z$#?pCJ)-G%CI0>U2X52al6M6< zT$w;a7lLr6HrUS(y`!V!U~4u?&QLvDE(;4W>(1nddbs|dq{Y!+{zY5<1$j|1j996``6Rkn1;LZ)dL; zX(*K%9v}bucrPdUaN))pgVm|#jQ1_## z@A}-0>1GZLk}9^E{Fa0ZN!2((G(Tj1qh|F@Kz^c1y$LsGH1FnCUsSoj1VWXbk-^~6 ze+%cTBsziXDkA9R*~!_?-(H^1aH`vs?s>1M$;o{|(^)umSFUy^7zTvUG;wHTYWj%D z0RIvd3+#xrfq5ENVx9)iC?xp;MJeZ~_b_nN8u;u%Xr4&cPni1wRrRe1#lBQ}K|$ZI z7Xp=5yIyw08ZgPVH59eQW~uYx1AlGRVYq7kJ)sVg`a_hwD7lXx+4;JoTQ{B-r(32r z4$0YVAnM}Ic>LW}17N{JgQu>2nX^$xskXJnLkHG;OSdsodero{AI@8vUuq4mf8P#x z#vmSRR$5X5DQ8m9%y*BDP>DG>{2&EAu%PsK&xNnX?K~1#0Uo2#SG%)eM*Yq|8McN{ z$Tjt>UGMRJB_w_WnQQ$kcs=bwv~OUbR8T$jt(~RK=P~H5ww$g9^pH~PKFpLYQGcq^ zL2^!}cvSy{r|kV7=W&pJ_cp^jfE>Q#IgRDqL?vCDYJS(N>tQAfb z1xq5e#s9>5DVMuVqZm%Uv8f3OlIf}4d*7Z=Bi+X#MD;8y!_o>kf1Ay!5HfoHVnf5M zNhG*kq2R;q7Ph&eezXw8^C3&f$>iwFz8k@4f1|ZKRXaB~7td}VN@UopXi`~p?;a+M zYY32pw7-rLC51>*a)CDQoYzR#jrvfc!UTzf-qcf!2=Qo?>?ly0ot>*BE5##T%}seA z;K~0x-zKN7rRxlz^w8#W+;&Q_)NX)j2Sob3h4&Zi46P(ym`!;|IaWCcBQ)Gt9K4^4 zH3d|Za6rmOIeXJxWZGxJyZ(pYK*fFgOD^`;o_dQ;`|kcRH`KzY$ z=(rd;@PB;ld*itzk~C`zfBlkylLzc*G&lgznp(klT(Y>B(` ztrA3*F(->kpz?^XKUtVk0N>^&`phO)^wG&FB`ZtBoQo@CvQx+S!;52bALFNT5fj<+ z*$+Ya0#GTNElak_2eH&w%4#|Iqiq{$;-137tq7Rp1E(#`>Z#sLkEEz*!+seB#Mal@ z@{4!NwVv`>#2*auET`c^L>y)SQot@^oKz@LSGYVsG=x41p_@Q}U$mN4?OU}jcz+7& zO9E;{Z11XCZl2j!Xjtj4El|~fY6^Lw0S^_+=G31`Kn^+Gk2t_xz3F|BFR@u%Qz)~T z?EJ&;tuTSB-w7o*p)7B*{bGG4j|&0nrjA+{4&_PZ;OOY`7b-cGVs{#Fi(#ncCb+Rb zxR>F2xhR<1wVYtIP)i%fY|)tV^2^7o3l2afA?|NX*HHdDh-H$sdo4xCLy`?^5x6bX$~ha@V6U@m-%mkngBLSm{}NDSbByPg@t|XB=v`5hofWS z7SCvZq%NXFgoeHa>aE`y-eK<)!<3o&BP#0OkEr-~Nsz8UM12wzyjV(yLX{=@KE65^ z55hn4XPIAXM#IPTw-zp(y{5HQq`0JoPW3Ng>9?+Ra68xQ1vX7VZlNl(T zHDcpBJa}+E2L)k8Mmq7qpf~SN20;4A3a)lMZ}iR8%U_I=6%gN96Ec6KJ)&_l{})w( z3?qi-|BGd!JRNCIIAw@9;vO3y^PhZ$e@SHF(7bC&M3|2J_!JeTWNj%7O3c@&C|npV zqCDCJ^1Jb8#!oKauwr%Yg|n9z@d6bUM@$?cVZ05Gz?Y+UH>57<2^KLsJ6<_P)Q;O# ze0X^HznOUAJ4BQO1Oz4{KltHQV`F2F&yPTFz3W9>6Wpw!{l9Z4a&rLd%~S9b)obix zpcF($Qo)IDQfk$?)*S*=!DF^#rwAgX{Y1&6uc!CRaGMvwjCiU05(bk5GsGkGMvx#! z`9UcM2S7s4aIY;NAFWp1TVURxzh>CyL_#2R;T7(qM@^Oc76j6wp~dU=yx6bPe+#GQxZR^!;% z9VnHg)(S+~5yp>CB zIAG^9TN+415Jo9q!>~R1(}0b1A}<+?o;_pvDR&wsy-*er8QBW@0F)UWLp2G5k!*<5 zLdsOQ^yl#ZtFtLjtas+*bN_egEZ-htzNc&JV)yI_J?rXtVYb}t>=Jva?=l1e@3*wo zx*|i;+WvAU6D=(*p>PH{wY86XWG`n{Y6?6GTWZ*u(*Fpjse zzgcMiAyj@9x$&BsurB4ftX?(4ZTbnq`m0B2bQ(pJql_>rqg-r42L4WkMolw>6pA;p z$mDYrp8)4GlBp+z7!LwI3E_QVDkhNoRPn`YTA#psm<%j5O+`4m zUtKdef)w;Uzu;h{YzqgvTerSSi)sgVX=X|#c)_?M2wI4WL=FL;y^)obwLgvhA#m|x z>o+PPFgEmj z^1$bE01||;h)|zCjpy-5M4xX1R3RZN8!DLqi|yd>P%rYo>1KDeW|tZDi<~1ksN~qP zAi$?>Y|J0HHau4B$oI~CQgl=*j!|f?3>0T{42+jB@DKSa;{8zj;n-3bM)9&)?Cc01 z{eMKa)i0i;nqClh9N49lnE4V${5T_hL9eE!<^;|;hTh$*km9!v(QUhGE5CdV&bdD| zm7N{f#8eD^f%O*uHYdy9EPb5v_l!~wr@?qrTV?OG^Y=x8Rz2$9-`-ztl+LOL4?)CE zNkM{)6s)*Hx3&Ukr|pATB}q zMBu}kiIEY#^U$4^|QWVP>)Q(EOijZv(pl z&$w=K8^$pT)KPN3CsebQQBv5MEvBNO&3tp?f{@5|)zcO|*ttRutE3@%niIyg)k9rW z=lW?Rpr-;cY?mTGrIMWXx`|1Gc)MC%4-p2qgD^VYRsV~)X89YVBjw)AEJ`o!`nznB zQ!>6}nU0k7M-si(H5XqkZSQ!Q%$zTSEpz{y|9>Cg|6eehf5?A9s2$8(yE2+Z2iZlc zO&Psrist#bIsWw#^Yne|g;IQCV2LouEnBbYR%tFy`jC5jikzAGvrXip5hO!o>oJu7 zI6nvp`S@{)l=0PF7`OlrQd>ty*6a|{Wm7e)z3ac|JJnR?R#v{Id`jumC*D`q1VH>_ z#mGedn$P8!;7Q9cs@2ICyKr)48C{_O6t2`%?QMeURzlsn$B(N0SdN|rQjr(7HHYF+ z`#r1H-hT3+F!j!@0bHE1?cj)r2=nl1p<~`t6armm7&%O^F@SmhV2d!?TK zwyS-DB%_2)$V*C3`Q6>^Ob28p2UUI!=MB7ShwW4!EsVgyK_J%$7>`+spU#ZO-PuFDG3n{N-1?RcXdpE|cP4-{q0$g|`nZ;VxX zYw|doB-H6F-sL4Yf7QvdOug|rt9kkljrUhmMS&`VhI^wq&7u%(8y*X)c^w5| zjAp8^)uEJ^^_CZbF@pxbE`!a-CdP^!E~{>7VQEkM9xAIU?;IZyypHBdsxQCxx%U*z zpmv3)o<0&dH&S%jWnlyi)fOEd(_B=})4faL2+LvgGIq(i_4g7Dd+e9-%jX`Gg6-4y zGn~$`Hw@u`h>fYzur4LqocPGahTpfRJa#-GXtBFKp#?q?IV3`Ul=Oyu`h?HnEU2&6 zxHY>BLHLuiGvkD<*{&qW`7(T%`q)`fnLSQoi*q<$BX>b7ylKkN8Oa(@x7(u3tnDcYeY6>RUp!!$69J2raZKN;n(>jw3ssc!_p2 zSYTO?@5C-IRUluOI^s$K4djnYO1QOLulL&0QtR}eYEjbATN?RL;9-*3kF(U2S_(ee zX4x(Hc(_b%bW#2=K|}%DVy5QCJ0z}Wu>ysOo15E4ft;2X3jsONjKj(CiQTpl8qTN( zpUeLdYP-5}V-xW#zyt<-+D{mKQibDn;)RP9A2@qxe~YDgTZ$EF;L|R8OA0cnZhil0 zOe{Sb0}CX3{u6wT1xbkL$-=(0O63|CYi@{ECrvb$R!AHhSGIg72yiFX!^fObqe7~x z&k&J{oySzg4|y^&GO}HNgut0r!T=Pg*F9IY*9$*4e@4m;JEjQ-Ei^HtJ-yr&kU`3<7~~`lDUT7Ia_>bHCQv=h{YP>jU_Ggwm-nz!3ExDxkmWejgu7FDR3e?A z@sgI-$JOO3Q6lRF+=P7Rk^k%gbf`aStL;KA$NY_7a&gH16uMs0{*Zg0l&8|FrKw3cZKbmCIeVH% z9_g@|s$#VBN*_fvvE7nwB4=GY3WT@M9X8qFIty(Z$l~zomaI53&GE(S72YUitTe^J>d0x9yl?4VUU$rJi813#n>I6^>pARxLjLKMW`9V9w)j9Do zt8hHHasB#r)mnQGGsRrZKYyP<7P%}(S+x|@T><4JzN=GgI0!U{_M_wg1sjG(c%Z9RWZ@)@(oJ1Hj(i?i3sng_OTD$C8x+h@e!$7_x&JKlrS?0v9H*sQ z`)mDycYb-|;Su}V1(Chvh1c`@X8)+1hOpy{ydvX{l)V!1+6|2xhnM8e0QMccZTpwo6?I zs}iFo8x96L4F2cOD2Wj~nf3;ZP|$H;9L0fr(Ni{T&F%o-30fZv5{*FopI5YK~C&IL!sX!sZRI!a?e0pC__~(o-Xf zpQ~E&bIS;w-}W1X%NR$r^84z6Q)rr5;m+q(SC93(##Mk^vw%)0yP3H->b7tkV)|NrIg z{`=u5d~S_4aQ$Wg`MfoGVB=4_OZqS6BRb?XD}RJ;;Dx}h?dhL`5zu8FYEhKts7t_| z8S(q#BDmQ!dOLtx?rqRdvb$K^ciSp{T&wnb`@-7tt3X>u`6GWv+P>^CE(+0c;wp|t zmF#!u^~W!-qj2R~&eq-5W*4??KQ2A^QB+5DE8s=5sn7O(W_ttE;}h>|etpRINI7V#$5!$&piu^6@41#Nu^pTSbIj?E&7CrmP$ zd8Cl0#nJ3{#A40zwd||3y8E35sh$Yb8yHR!jbq zI5W>Qdk}=5_v6c#s0e?1UkPAw+INq1-oC-%j)A;xt`{1ta#n8j0i6WifgyxdL;_Fr z@)3mjbCtG(!q3w~b!gzui2r%}JAx2D=rMy6M$*e24J_$9*PBf}-@PFsM_`g%XA@#` z`w{%|65R^tE}|QQ=lOrW-X}o_x<75I$K1MI^+5sWGJ*XWm!j-R#dCY25OIS~$ptY_ z?g`kF-lCf?y~M2!Q#qCXJ%NKzPW1~Vr?D{;F5D|?7ZRadsd3iMT2#J4XN;Yzfz{1q zHgK#ru*1-@Yxu34bQjgt+;V(Yx`@2Ld3~{IPY6NDXe8Cjd`p~Yhh4_dbF4Bu=b6FK zP}~|pBgcbJR4q&ArHUE?rXoIC#a|!pJ7XSG)4!jV*VHwUY!tix?Fij+efoAhpMRQG z(G9=jK9Mae0?f-_t1L2|rMz~xeN$36NI#E$0P# zo(h=JB*fXX<#~zZ$h_(At03I>a%hnDv9qd~PI}G5t`o(a8;85JxR8bj{Zy1@?khS` zL-cm%u5gBGXIQ!ydcb;35*B4;XshuV=V7k!Nm~=jGUtyM5t2M)=QCnW%r?1v*M6u{ z=p!;x(+^k2ac#*nNLI2w713B0m@G9g&Z{L{ zeR*$+!5-Juyr8+_Dk7N7WvQpJ@uBOc`)W_EqD1grnS#R7`ZRy8x{FVqmQ?fXf3Eo( z3hf=rd%Msyj5VW9-y->VxkIlX;5oxr%xhAqNX5YvMz$zyFqKP-GMf?%ahIUPy#3u@~S_Z{3uPR7)-M${nwS`9{91Nzf zz1H*e<6rW|8KzlizEs*#!T26wi0)C!Bm0!gPl zLzUtZMGZfzhc`T8rWn6a(5#&1q9P)Ko6^URc^QujpR==x_CrnSm4r`21|EedE^X6@8OFXD`uh77J{5HI=RK<$6vZ^Q3m~FG> z{b3fa&E3mwibvLnixZWE7?N%+>V9S(Tnp{$eQl+?+h1!pcR3@igcGbo z)6X~6S+d8mmF29s~H}25A)TB41=2SC%?wxJby|LKG6}nrRosq4zKHY)8J}B3b zVYwa|M>IDUVns&vW|%!g1mpElU&Nz@hcC)y$@`EAca-1WzwMgtB{Y=x(!)QFVsNce z3nqEL$mWwUy~kmCpEl>6&c6*UId#ia+cMNuJMTUYFCO^ZC-a1p*89dL1IJi;uDJ79 zny<*w2irPpLvEw+WXFYBRUG?2CD=3j4`py+=9@co2fFz0I zl{luJ9>@53_IZR%bl5byDp} zFmA@k|L(vc`P$}giI#99lwqx2V~x?=pxdOQ)3+x%%rv5|@}qCTOU`kk9Mi<@K2XCh z=t&8cU!rMR!(x<8$|Zi}Fg$#QFeLY+R8udtls=>9bqHpCdFx4m!v5Pwq5)=|Tm=+>trJ#zIi*a?Oh9Qdo9k%5wfZiz<7Ek>aDO)dRrPc#o5rCNYPQOHaj_ zL&W04gEa;8pxDS}*T4t8Hach@G{}pb7cx+}l3JzC5R#8-MP66>ebIifb($Iky|tGLWeeE^KQi zmTq4$MG8M2x}0W{DT+o|3Q>k+@T}S96|w|}e*P&}&8|@Dh8GpZ9M3Z}O=O}zt`BqZ zZpwz81z)(IqQ3cwbYmxp4s(;!Ky^>?GmJ@fljiP^bhX#X<~6@3zmeq|rK!cGC-j#! z=emF1(~msnpSb&B_Ww!y`6TlWdf4wBs&wt|h>`5Ds{i@5($8X^S`!`|>9EJtJ0@%V z-hH#z^M6D)Sh#&YJo>HBV#a_az@J}Ilw4GohCHr6U}C#MaC3}ns+qouj&jv-^V6qd zCWuP}I)2!FaeA+CC!*1fA3~Y>G+lfMO{nK_9w1OK{kDHf{<84QRe1iy>Or{nzr!4C z2wPD7h_V(~;thREh-X+>el-uF!qOJ47?rIp#3mUO z^O08jiYjY>2Jx+1EztrSAw>9%ul`?#>HmEo`+uAW{1f@otb6wg_nGqBp5bTyUWR}T zo#gt0Y7ZK$CJ0^aX5}UVUi0D`4z6!V{a$bXxa8U~72QUHc9_L%Yahy=|$m>A3J zTi)(T{sl2)SZ+67Oxnefz7T-|hoH8caUd{}Il@n>Zwh zvTQE1;0DI_L2Rj!!p&-!d|0TMw~!YQ)xpCjA$d+9(9`Pxap>bn?*BQS^_cq4c-Bp` z59dAt&05t(U&E@^_df$#Dy^N+rf105;*#0Y^ogVvg6K6(OoH?-}=%3#wufhF>Z=rJKGC^0ipX5~$ zb?%Ns9{ibP%3tq@RMGa~{j8(YJ-T`8WWv{CxBXsip=?Vl71w6fw~fV)5VXc}J*kVO zSN};3JNOSc;urnTzCoZUUZzv)QZ10kCT>Ly`wPV?$h{^wTqE?7`< z7`DMjC@DwD{`|}Y=h^F=Q(c3JpUlieUnl&M|EqWf!4T(+{^}xi0VQ3z`(_kQ7fF@b z_fq1_Ky?0h3I>*L^9oVBk{u@*RkKB`&)i*2hOsJk9=cM<-s&sYr8vbgb1lhnEHd$V zkMimAH<~?eR`*$a3QD?64Y?F)?YvfcIXe~B7IV$DSHvpV?v5Cew4ItQr(%Cx=YO*b zm~vAwyud(+=&RJm_G9W3aJl6Pe~*n!E&d3jTb9fHE6Ywey3Derq199N+f8<*Fa8@` zdoFKoPtn?6wOf8JeM-S0IX!qA;=Gni`3tKmOkR9ywV^L{LmIO^@#B#(1c`66+C+7` z5*%MWo%Z=mDi_fqPNa|X`2>5H_bz(FHar2bic!2fxmSqvw|cKB5rak%voNV(d=c-G zy`p}09AM8t`ZFU_NPQ%zetYNlCliK$&OJA#<$n%7hSOYutRI3$<&KL?C94s-kQc%6 z9vmC#S>(GLH5_tnHzGAJ4wv2F?1muebvK&6Gol|NRu?Y6X6Dpg3}TUI@7_;52rREf z`9Uxiw$LZD;62<;!alLUNSF$b;LlqC3Lqiu4(Q~X2nT9o1ds0eFA?o|>v706iCI=e5^cV?j+@9&HIkV$Kf{@HUCv#swUx6(s zCoUy1lWzax20gqoT-U>Ld&{DP`24B3!Q~U0puFPp39hN@Kl{`ZEXvORJc<4=I>C{2 z5QpRYA6x)9s?ZzeiC7V+ID|98ah?k}Y9@)&kY2+P#SDMrug5~UtqJE)2#(wTZJWY@ zZHiN6D2_eKu>rQW-%$yV?=io=>5BOGj_8gPrHfN)9S$esv9B#=Va zS?at0Yb&LRKfEFEM4lQ|GaQBiHSnti!!m#3@#ZIW7~-TLDdFf63j#(CY=I|=>8P64 zu)lnr2$+{vV(m_#xJ?k_M=s3!UQA2#e*s?HLnFp&R7vi^1f&SviKWf>If$V>zWjfD zwEQ2RMgQ@EzjWY$ks+69T`NaR!SnQK_a1Qh9qDnTTfb?)?k^Ej1PVYV>qTCj&8PKa zrdo{(A5i5MU3BxIc-fMmyjqb-!Pj*-JKGx$cx1G6?Gc~1hX)2}08wYj+Azv<7WZHZ zvDu}y7B8(|=GGQny`@!&Hc?zIB>LS6Pgz((z`o(R;knSmhYt~60RehogAt2!11h3% zC{AZAhK)i{__m5>#1fd%{mxPkbc8T{MVXAyd2k?l9eDoTb<*MbNKJ(I9M!u@Im4zU zczt3pVBo*k2}~!e3$uZk_CTm%_OM-M zv=Xw>>UpL-k_lLijk5=Fu1nodK~BSo0I~>Jam^`=NifyPW%Q}mna6?DB?o!66F3&Q zw>2++VjxRZhGS42+ulyk9JUV$4jHXpu%T5*cXhzG@z+fNueGs*wPTZCl!zu>hakm> zVZ@Mv0s<=hhH+*Gt2X?%Z&0~oyh@;y*xB8ciM~&S|Mr8-hcClyrn9!S@k}?t5b7RM z$C{Vr0`7*dH<$r&_j|-1UXb9Ql3C^KUI??@y#e({LLTYHc&TjkeV`h-e7mCCt^~uq zw;%#W$uB7xw5OyDdK39v_pZbP_C%LyXP*^oYhjc(-G>M&Ha2_&9Ua}j?rN&l!4;rk zz>jB_m($s9r|ADvDhM^Vob&B&rsWZ**<2Uz{V8mB|4w4$A@?rFAUAh@VPPL9azr=c za9k^cTXnLPD%_5bZ7Cf&;$gVJ7Z2)h;06M%KenO9%U61dB*dOO&yv>l*QnSa{`Je^ zoCwcv--=dSwnmSn5NvDqGC2xXP2EslLLBezEvDZIvGV_XrEigv}FYRrqW51t=iTg~s5dAT!IYqmF4ErY<_1KJ%)E*Gya1WPVbZ>~-@!;?e z9?qw(UtZlp! zYzchBIh}f;&5b_`@QM@^S3AH7dbgO zbvSO7O9E7!XmaSFJ_5Dsk7t%KWL2uxQVG1eM^ilOQ&rz!3R3cNIwAwCmBSj+|Ij^K*sLL%HvDxj>VjJkpurD5Qdl{1vkKj z_;hvY1cOgI6mnwpEiE;b*aQ zkKpu|3%k3QU;lD7?5|8mz@rHpXVE^y5#}nAl|KYKE2PV8s=P5w)uteAk-+H@HjoN5!}k;i8r09ZK}rDySG5fi`A_*2 zny4gY%6fRH*Y>*=5vdXh;#Fy2CLoLM_RXK~cWSsw$&$Xh{8p?xu0ZKWoS@Cab#<=N z%WHCof!S-0S|NPVy+ul3q=hO(MZSAimd7)zvaPdq+ zYB*zh@IcEta|pL5Ro6JRJC+~B8qoA;VLz%L>D^DGcn|~n&IU7sf`S_M zm07SVhy{LO-n25ZG#$>$y>N@2>PFPXGx@7KITUG5xv5fNgT&`40|UwQ$7{OSb@#a) z4*h^(L7iG+HeOplHeO;$(6qJC7A|`}e6!Z_8*n6&-;l#p_tS0(L^?_XBV9gMWcV+% zLum`IV zbn}$I6u{yUl5uPdNRA`W zNlq?Xwm9zC2LJvowAdXLk@q*P`yd*%=2|^J8fG8##{e_e;5FU3xjAzytCTlE!=1%Y z>elfN{@qkpD-}M>bgbT7gCr@4_IGrKN%`pJy~Y-kltle|?y(ok>);9O^v7YMpkC>c zom2)p-q+BNXYEC{J~&>()ciUUQQ*jV$l~9=P!ebIzGMdYM#xWrJyqXG6%)$UxggYm z!PhWFeX^2cwa(C^!O0#y%Ave0Zf(N5ST{h`R?C*m?C(E7#&cK-BDfO4Jk=m!X`5S!Z^F zR<~Gt&j~-Yu)WjykLV4I+n1|PUVGoADDH}A)$!2NSZm9xU<^r>)LSdf`Mffqyhe-w z>Ib*uzL%+5WnYe%B9bn>-SGI9y*=_(NxR{Ae08qk^B%$5P*_ID$XFbaW_<9tQEWCI z0MXzZV6*_c_PqR*3cUYcpB%Misdd5m1I*o&t7Rk$B|}YxY2d<_fDsE0h1J2S;hbmq zbbXD(fniy-puTw=(mDbP8YJyUS$$IW@4CRI=k5FVn{lUeeoABw`6Lka>-|-4QdAMfqOjJ2qJen}%r&U$(hAU%4dH~%9JWQz?gnjO5HB6jTdpYwvZF#bqt+Y&6+00D7IiSd| zOsgN=;QNF$5}bcYR|<S zI>Qx+;1k!r#@CY*SCP{049&iVZTZB<&nGsG-_;<`vn-W5XkK%9aduv~sHi6y6I5ko zIO^;z^wZW1TCvF+a!CAh?q8CK$3YlwR(ER+KiCtBf9!c>_e-NIjR5_Pzu&YbIZ>;cnDm2XMaKx9hi{5Apafrp##|xpyELg zhjC;Ekb-zhGq-!$^1KUn6V^vg*dYL8QgX7R*!@MAfaN;MZTr}zKptP-4j+=UsNDm( zpXxWe3~4`iehH3Ir5Q_Kb+M{os8y?Q`xZ#Dn8oX4TU3KF$|o@8g-CxIq{ttY%kj=4 zgiaVw{^F{115bYAS^DLj-Db^c^a?N$D|0i`*3$YS6_VIEcKaKSdzSLv_S)zq@-d08WZWcG@cbSOQ)fAw6(XZOMkF7sF+;_{{kKl z9sT+4Q7S~f+nud&;5zR!I4vG z=}(j5xS}0bfkqpHB&v}QDn0Eg{IcN8~g^Ul>x&u`4WkKUX(#Q2{~zb zNy-rOm0b#fEsxpx<*%?`0ud{ephUwLBWS(wxhu@UbO%=`SBkN5#nI=E&Pi0wtFnfW#yq_vsC;W=zs;X zuw?DBE*}ThRSO=2c7EyGcBIxDQ%&2_zwF?UxVktZ1-jC^QD+l7{N@1Sn6>kVW}LRm zd`LgXy`}C7^EJvxmDV!JLIXntnWxYBDg*~MLg+Jhqtkz8#-_#+u8t*TURiZoC7Q-5 zbBNj>Y;?lueZ9gV;+7g$0a(H6b)R@b;9P1l-Moz}^8M1t%gN*-B_mJ1gq^)Y2c4%? zJg9a5FSe>E${! zDnC_xY*s9~*Up|k{Kk6r-H#8>TO>}p@PTv-E@#z>_XQt^0!ulAwPkglIgS63Bym=2 znNZ%-^<8=<|6WSqb8yFaR>t~z>z?R=)5)l9+^K*(>0+8m=8)oTzTk2><&+zng(`|} z_$|$$*EL$ZFye>D6f;jX28%oHMP+B$SdO;-`to2n3a-^5@1t;&c_iFiXH3njL-kP~ z(U!<>4pyT%bPb#b5tX$=LsRTm>iZY$G|uW*%NIC36BDs-@xa0|yzLV0?8LG~12l$l zUw@;gSd3co%u`>s;RKiLD|l<52vZ*v?68$0l>GemH32k*#&)J2pDAI@{J> z9>JMI$H(!y@SdmiS8?yDEtEDL=KBoFzro^a1tL^Q$u8P&hHdd{PuMxA3)>~8Kvtlm zs;U}#>*YB2VoVPOpNO^D;+?m^OdPE!?;EiNN+)pUZdbI(r$ctQ=(R- z*3JFfrS?($q$7vcL!PQ5oyLf{&zo5jJ-TuC@8=!WLGm|QW!+vu7A2l$wZPuurD+Rf ziEc77rHl4%VAQ^4+BH9POwC*lb|Mee6%06)Ay(Gcyix_|3nU*L8w>6I5FoIv4Z~AHMt0cu8ReqxVS$*Q zf0&yLjJ|(D0DE3~!rsTi{04xknPB0Ee9qh&70fq&nv7<&TLy>5c7&U#zyaT@l$JVy zKZaabB^x2tACovS3K-M^o~T*0VqpN4EMKlw#_?!F6iEr+av1tMTvFEuZG!w6GgqTY z$@uJ$sYB#Zrz#M)CDigxK|~+c&3h8s7Dk&zpAb=f1BL*$MeW{m4A7nho%%oMNjKCM zjiBwkYIcmxQzgRaEnOerNdz&XX4|kV*a`Ok7ZeM3`?-^H3kz3wD>IF194oZEQtCm4SK&+GBL&%bb$ z9i(ROe@E1V(mQKP^|e--*5oXrh+FfFYQ|@kN~Xzm9vp8A)x8+k3%6Rzc#gzGMSYs* z3V#@IU1C3l5{A4TF1XGC_z^ru#Ugug>;y${wEGt&Tvsnoo!UwFmnX#x|D@^PxdW0kcKhR_j)GbMS&2A5 z5L(r&$`<8P_3KG0;(Wcay650}j%zz-7DM<_=lL9EK=*<5q5|YYQ@sB8Xnm{EXA7+% zRC1s4etRfBeNC5_cfHJXS|<9Eo($D2ff88AJsD~c#7H;P+aHWUk9hLyn@pM(kI``6uXAB+3pT9Zz+z|JIY6c-qWxE=4%gJ|KZAsczu?hoz!lHg zVdlBY(V=1E#$V02@t=&C73j_^Tl}B>&iPgr{bNF%3vo}9rM%z1rR^2~8sqHWR@$RF zCQ>{Ip}0z~T9*kzoV36|>da&;sz=Kb~pR(J4Bm?K^d4^w$c|hFQ$l zKWW_j%6zeAD1Ks33z^a2mM4%XCL-!=HaeJQEtQlAp~qTFSq16$qPklTx$AesrVDju z$eQvmU~wjc1qON?r|_pgk5UdO(#Tm>lW;-cgpcg>weS6ygvUNPlvGg78P{8=F;eQP z1$qudu{x9W*G4O7j^_oGl(5ANnfw58eZ_mzE0=2si}NCw_d?u(kLUbdVwL-?9%&}Q zibsG6BX>(RJUR}SnZ~SxwlkCc7Si5Q2^CY-+Gg)xE#>BWlyw&c%1av=tLk9@kneR) za6pS&)Z07UZYS7FEWi#gC@UMbKevHafr4kav={Umh4+?byTF!MeyMcXcj{?CX7x4b ze3ALcyu`RvdHI_1QG$3FE%5V)3DK*JO;?R!Z?_z!{vLiDC{$aj!1*goK4 zp4|S0(%DK(s%mO9@`d;OtE)lY{Ss*I3LP%sIl`YN#q?qM6DV5J;Tpl7lKK*xl7h+- zfGEtHgkD)$bfDU@bzuAO=LhafyIpdmak=ChFPS)qwq!Z!$^jDx9(FTes$Smy3p$!V zWKR72K1*U^7DA`Juq%0RbQ-xFP5{(XWraQq5+-B@X1Hwa`m`mmuQ3k;pKiY6$Q(2^ zl#+2B-F)ZC#oe66#!`QK@f^AB#RGJqm+$`qh?nP$G*GDZJ0NC9wu?z&S?6&$ausjx zYZA*)NegIGC0acdk)2krv3}N44J~tamkS)<6vKieuX%vBEdklYLoV}JcyRdruw{=_ znh+a1UxvZl8nCPPW6$7PEc(3K69hQuVq`7Ann27>J3eRLq}UiMO@e#~2I~{R1cFu8 zsx{G;uA|wPTuzIujOx{opHshKGMo1bdebK}dcK-)*|*TXZ2}E&6mn2DTIzsl4k@=N zU)ABJ*6*GfBg=BaU?60{6NZfhauahX*MLoi@OB&*M|eL)pjYKX9P=G>*i6-TpuOQV z80mdX5zBSEOF$s9Guu>9QX(%-r(XTiW%C#t0qus2vl$!*@LHt)E^erR zQLq%#Mem#l&La+0rtF!3I2RUBZtPZ5e7n_~>O{QA5ScaLiR*cD2B0BGyub6Jom$K< z-)Z8OsCbP8sy3!$TwT!aE$A{6fy^pZ@rZ<@l)nY?5aEa zQXKD{WLBB(y`?(?>FSSqVl8#2`B3%`wMS*FaB>OF( zVw2SAxspQp`p+Z{=wx-rhrs3uk6PP&UMjM^A!hZ1U|x_?kBmf|m#7ixY&|yI%hUDg$~!y9a6CA^ayiZwu2pvf2+(CpPRSo z9FmSm9hpuV_GjLN3JSuYzmTn8zw0rypDfh<$6slz%vcJFe{V&@1F_3LoZN7XVY@aT z!D$v>aFdApD7vZqWGr*CtP=W@5P=2tT-nWC2ftsQIKpH> z$bF9~iBE>s0n(Fz1nveA(tzgLNFG5?TwMS(z}@bx@s+`KSY+9+l zNlru!-$iwFy)1wBnN?0-I`hgFMF6@4vHzqt_8=%G@H~Gx7m_z@Jh*cB%gKwma zy*#;m={);#kULYlGwFT6fqJE*x3?@Mo;_nIpc~K0$14FgQ7*TALKl&jY*(bWds#(* zjKRZ(dI6M!o@#S3c9u$op9=b3RgVQ+v71cRhCyphTHP@g%A{({{yZtZ08-wzSmh#R zaLwYo+QtJ7nY`)?2+M_3ZegB$I`_>`Dj;*eh9eWb)SpZPwt1p_kdn6d4prf$jRkGzEhKpbE&ocfH)eLlhjW^bxkT37vAH3d*=FA%Wq;*$JL#*3xT zr?N9}{|%OE=LXU1PE0HhBqq()_RVOEY;TQ<8I~jERkc?u*N{CkYigWo;}=_6T3DOZ&u`I@}~ef|9cJ&!C_eXv%}- z$hHNMIavIwX*;}tc3VGFd{4{=aYZ9$0pmj|AQhgepzb{CpR%{ZDE0Q6vQFr^n>;wyMG&;nyLX|2nJ{3eoBdZ z{c>?9Xg*~Gv*4(x){svp zE4AX3;9ce6$YOR2_FAY5r$0oKQn}>`Ezc|uCy4YU6N2VYeE(evJq26N>t^q3b%+!h zRA<$<)u5H9n30iD0Miy_KurBLv}@4kNxY(PK?&;DfDF8&1uwL>ETp819haWkSC3{E zb5x)@bkj9gt@7@+6oRRs0J>kg>GAGfHD~UIE2*d$uV1TD)E=Oqq{!%G3l0n65JR@+ zh1md(G@!)v1-mX_{3{6kfK@@GTu2UKg6NvBf0&E)=g$Ktk=>jDr-v);kXa%p2#DDJ zFuh!xqY6Z-K2zp$`LEhF8&;E@Dk7}pkN5lT|P@Ek$ z0d-Ab>dJ9>kT`RS94d2EL?Y8%g#m5VY z)M<8}mXN2BKMiSx9vpMiXlM8l6W{`XYy~1LM$peR-Z=v)_uP0kM_sN;(jOIOo6G8l zR&d;)!G32U$_$4JG73YYYD@t42>aeov0-!pY3QrES|_m39T>r#Yw;JPm6)sAQd}7@ z17#aNo#Jg$((bQ}Eg+;#9idXr^Gt7#U|M%iJg;6YCGP;C zVLDf}0iNZ%fi8yOmTHIqp#IVgjDQrCh+K}vae^ZK{;j%#t9oY;BtW9JK2a2Ne{^$0 zAyX*``h*qgUA%{#71pdHkKhSg5|lZ-vV5^G&f2!R1BuTl!29$A1X-dB1COqh4>8x1 z0`xZ?;%fPIQlo7D3QD4e%@_?({*UWTGfzd7YIUM!X|&XLy>x62CpbX9{fB*T5s8vF zb#H#m%bWLziXuvIIVD2I95Cdv(M!{L>~mBSKR!kkW-HYSm?P!?e=0SG?pho%SP>7U zN&d3mCmIPPnXK%u8eTh-SB}t=s3xWxWH;+Vq7;Hilwx%#Dv=Z?@iZ$fP5Ja_MWo$2 zCu2OH7s}}35BQ`Dsw-8WnyrqglRSj-U4-^j%=*U-IC!r^{m30qqyG225X8vyId|8( zpr$Ji%Ni!=P`r_eU`#4=F?(QV*PAVD`M}=6e9M`zU!w*)-S{efb)0@fy@oURqE9IX zDtyuzGP+1qs}6MBMGk=v6^ZUIF7EGab#^JXOkDAvMlSMpF3(Kkb)Q-pOx8Y=&r;Cc z&H83r!Ltb6M+hOH=yY_Hn-a6Ku=voqssTmQJl2nWUYJui%|CyVv;PAib#tTL-gSs8 zJ^hK1rR>w=qvoP;Dg=~p7t<0HS?1POdB*rt`JR{X z{7aY9N9xy)?r;Ki2B=+!-tW}+yzVIgbqf54!%jpFp#eKY4Ut?90e$<~V*bFMh0 zCEvw49#7Q*y<+m4J3d@oSv6&g%gajX?xcUViZZK)RR+2w7q}%Zl5))CVUDZTJ#opn z?EEH-(a_g-H)0kXC7wDx+yerU(Hh!G)Q?o{B{jX!BZSAWn`GQ#^UCyKqNou~br3O@KE{TiWvzfbcQg<6yBU+8DFoulBDXL+}4_gedG$3O{s9XM5!zNw6Nv`XT5xiIojWBm#+CrFKB=gta8Eu)tErbjK~ko8>X zO=sa)CL3Wg9F8sA@2IvXF+T*^rV?!ZaczriiY+l#^9$vU#5#PE&>cqry5lI9eyI4c z{r-KQQfB}D{jPlv z*Q(HhAB_F>e%Va#ZTAYk4!HadnG&nvgwWdg`UxeNUf_d{Sh&_(82kRh$@uNN-a<H|ITu*r{q)!9OU6JvhB z7F(|?K5FjoXLEDu_fvy|_^{lBzQKI_pP#s%(X*?hl5le@`KWTn_*VTTfPq_4=!XL5? zFhGsewv({qD1Mf=GU5QrmsZwT}r&{rFZ@{FgRP}b{ zyiZTK85vNofHy>QA)UbKhO}pl-%=OY z9y#cD#V2mnUvgh}5!jB?Jl)?CJI>mH@xr`t=I=VrDs$^0r~2WH5XycyA^=p1c=~G9XyW&dD2Fv4(H>ve zG?PLZa#LB3rW25@^>+I~!}!M3V%{ievs_$EY;K9I?smQd>6T&^^t8b2*YA8hZ;Az_ zpMmHI!T#OBtl=KpbtfKePTxhw`m_w(ZO(?X$X?QwQ0#dLh$=o#?Q#KWtiGmgZ3}zp zh16UA#fa8C0b)ca%+}(<4s+5}KvQh(YDfx>JIzPn^78gM=tx^Yt^V@UHUd~#KcPFE zc+6?Z?A-;^Wwn$iQ*jT&+d19?#=o%Dz2ab--m#!F2Fq19b}adEQhs0EU=F;;3A@-)J|(xf{c z`@`}zL1?yAAj5!VvR5PGUN&^bT zdY7@o`pK)i7CIPDCE7LW%+)pu2ppGgB_0X94SI8rLlxk=a{GhKAp?>c{w%i+kwri zjY%81drOy?+t*khl6ih8zaL6Gzl47~qd_xqG#};uU?TW zWyWK5#>+*G?)?ofC_ercKyQv^Mr^ribh8*=u}5=l$miv}I@V4RqBo zp6}0A*XDek>ek(D%*aHu7q&rt=-<+5$5Md@eDjirCMMAyENCnw(y*l6}^6I;hoJ@z@v}y zBo5D1iiPHy{h6$G?|DcKuoM*z@TPJj?V2NsX?J-juBIx`x+En<9YhgL&QWW_c~4m# z8Jv%uW7=-#N^LcLd#tOQLQPHmN=xer$J_+HJE*b2EUJQ8)ZN&Ks!kHGRL1LhHr53uFrS`ZepgU?%$AsuCKR=L*gjC< zbGP}yYN^?<^Wj3i^o=XCsWG=ID|0LDM1ITBPUABCA>s$m-JnfGsl$@`;d^r3#hhm& zIcqD`XWV~m|G4RU7FvfZWNTl$wmAQ{@kP@|y%b^HiO4hS4aLfuCPuMHJ7erp8a)=v zje)R|qT&x4w}_i|H<$K?+G`S8Y9H`?v0DFI$Cke-qinf#Y6i&`stKJ2S-o@)C# zbfLUv%r(?779h-^)_Nns*G~I9+}``iQBR$@WbES#XXE)B0O;5tG6{Fx1 z4_i|B?AAy}oW5IGY<9$RJGRk^5^}j5lAW#hcXdn+c^|9{CU|tj{z`S`iIWd~uAr{k zFgs+XbyzCdQCaiM(&CfW)l{YIigA?fUn~|glLjFvY`d$xm4n_zrh!Kh_!NGR#JHhZ zwk`9pq*|1fgG#BaBpA|?v? z18b|RUCn`Uzb%+ajSnKDonOf1;NjJLv7w(Tw-1RbEBzZUrK_!%s?Xw}LS;?ABjm0d zv`!g$U3&1q+(1xv3G+v-ji4;S*K@)JeEjDxm}QokofV5mk51(j)Nh$f2ep-bkjc2` z;o$*mN^aC3ErUR)e=Vs~+hFWk(3`KRn3$q1!vpP!E0?PQH872rUl=9li~mu3%)GV1 zR$ocEHkVFwVr-e2UZp^`<_3j`gK!)E7^gfbe_}S7vuf~eota}FrpO9@L;j~N(@~}L z`G+rUOsqA$t0aQN|NPIxHhT^udl#$jz|6YL-u*~{ZRgkzw`HWD32|Uvn&j&rF0Mm0 zkGICEmKScnC-CyqoI=GDcq9KA^9|M=`WvqVyfmc|cLmUWQNQ0NQ@ZE+^>)K)!j1aq zeP`BtKqA|fI$U)xSE?epWip(#d06Mm8|Enoow?WI@!+pLS2FM4`@lwAZF_PT;-Q99 zf8tLN;lAg&^?$W@rSVX9eR#6(vagXLqHIalEQ9bUA|X4IWwH#}*MyKUNgnAT$x>k? zONy~?Lxk*MESUxwjBV`8d%R!XPw(gV%R9gOyc{JB2F_7OKQe6TJ@)c)29x}#lAipAB{$4@J!XHgxtpv)h|tV5(Z8%LG!Hm*Td z*x_~g{XL6!RUbU-9B+Mfn$*g`*K02ChDp)wv0K%NysaneWxwGb4==$wl_;6w8dv}` zqad4{X?aL+b8<%7$Qx?~f+O9HR3Yk4)4uYc&wA~xdw7};gM${4O;JK`v>zpicSd)t z<+YW&A7M{+j-X^rh+xc{RS{LcMQ37)_(M>t@|PrD*2G`07L>XS6$a=HBlT#ee?nGW zj_Vn|=kO(4D(485-j{v#vz-a#ig_}Vq(RQ^bmTa|w9Ej3K}&3iMg zAmvsFn^4((u&ip|6v@L#KexWT7jQFIncB?_>0vn#+%VzWB$v%}IigX-D4}5Q@0ZyKuSC#ui zx|!DzzkUQoBxXrnz+2;IYs<8V$DKQ&J?VXtZ9PM%Y-3fWOU%*;q=sg9cMl**jeq@G z7~LRBeAvL*jg=invwE(=yS{yEk*D8=12+E9!`+J3V}J*6emkRc>I~f_B?0lif}B$= z6$CJnYV*9w2D69rio=-Bz_zf}3|WfIjnt9OuHIBVUwk-f1JzdX4XDonh!Mw6a$lSr za{qE7YZ;lCw)}qTbZOZs$aBd!ZD9B)AMx6n_S5Xtq|oEzGk`!duDDowKRhD9L8j7C zu)-!~`14f|yVE~9rtl$CG(uK&z=D-eNYx?SK(DQLii$UDL&j!O@-PL|r0vn&S?cSN z8~xpcrh8THOstO!eTO3;C8YbO>NqivAkPl>zr09OOwa@R$k4G1&feZBYe`}D2$M*d zW+VETO|mx&v3zt+=%{ zQBVg;$fQ3h9dB-iL>+AXf|*QGmL438P>NO6)YsMZ9+Z@YTU>r<|_f8M+Q=Pw&bsz3`)EeNwxvzrSCPUPuU%k^U?p;d?@d zRIYP-`7emf!rjZV#N2<qZgJ>6$1RnQ{G--=W|+NCOzWlkQdVN*5RNEBv4rBDnJO{q=8R zc!oCu@kwi8NetPE88cC+ylKwlcH67uaqaIV=#rr7gtnmgrh=7{&^e z%tb?TNL&9%?6Qkc!Qs*JhN-L9XMZmyHFM~3EQ&UJy?8;1zWnMdB&;@!Us#ofgLz>y zwy4U>W7-Cs%HdEdN@p;Fc8#fG7i4)13=C{40@dubf^^;8C7GD?*Zg*7ag>cMn6Ix~ zW#x=1b@YO%`f>jt=N&1tmO@4@a~sR{Th`Oy^~D|1`6D&Vq@>_$I?;-0rAU{tRR??` zd&xd8gg8_Wl)_>jk9Y!`^=QPDV{f5B?%Ph`#q4px(8(ic-M44~%Mf8WoNJebKc)hZ zV{c?!>gwy8lifKt+jdk3AY3wD76wobcbeYj6ok_7sG#bE#(A(8zdQ?OA}biJTB873Pf8RfgF5Qv9up)9%r|@KtRQ}J-sL|-`S#C6`TLx{)7U3d5j%c8#7DE)g8Y!8`n8XUYLil9hd2U`rYq*~Tn! z7qdqbzsbs9Dn$O~tB<>RkDM5(J5Zn^ zYSopsco*$(`*uv7fB;AyIzlj3;(vCfLFb5wlxdDW#>%~`yKgQdxC!|D9Z~#3$+=vu zD5eS_#hIzEwpBqW2hAnZwp0`4bSQOrSHocVso6~({L9|@lZgF80WI(R{j9uF zDPkt|f&a#qF*?D_ zPtU`jpSY(5(k2kkA(ms`AeN3X?EG`7vp>$V932L{Q(7&1=7`p6XyDLPVmRmRT`uj* z1zCyE&L6v>CzAn#rp+Gs%)kNLrhQV8pq+zg959V<&5%g%6x0(-8E_eR<0VsVN6Lh<(zvcz zy;p4s%`W}0@tF6Be+n91q3p|i4S6IY=b+X0p-fKU%GEh#9AaZ}K)f_{DyGda^>nP& zIiH&BWj>#~7R8o-EO!dG1-)UGw{lp5bippthd#b*C?u@?kmcmT7#l6ryt+>IDn&6# z9|}^;qSxWVMUfgGF&Ip64i-uZ-+k*3KlJGLZTETFhFuKu3kkpsgjY`;PXs0pe?b*A zo(?0CFe@R&mwK!&Cj#{WSZplms3QLTw1)2ImHS1^S>f7(h{e0N4ep4>mD=6SNm$;0 zP7Z&i8cpS0>f`L|>qwx)O!z$VQ8#!n*0x zSV`P}QiptqL_7m8?Rhc%@{15gu~>lN{%={v|G)abnE_JMnTZ?d51ynY2>2KqnCh3o HoMZn5a0QJ9 diff --git a/kotlin/examples/AndroidDemo/docs/e2e-signature.txt b/kotlin/examples/AndroidDemo/docs/e2e-signature.txt deleted file mode 100644 index e0b73a4b0..000000000 --- a/kotlin/examples/AndroidDemo/docs/e2e-signature.txt +++ /dev/null @@ -1 +0,0 @@ -5anzHR9SygbcVK12t6gyvjkAUaM3qX97TDErSFbcUGNTBb99XuJyUJEsqsceqPMKyVxSpxso8vMQQ8vb1JNFN3n2 diff --git a/kotlin/src/main/kotlin/com/solana/paykit/paycore/PaymentChannels.kt b/kotlin/src/main/kotlin/com/solana/paykit/paycore/PaymentChannels.kt new file mode 100644 index 000000000..b0ff0dd6a --- /dev/null +++ b/kotlin/src/main/kotlin/com/solana/paykit/paycore/PaymentChannels.kt @@ -0,0 +1,216 @@ +package com.solana.paykit.paycore + +import java.io.ByteArrayOutputStream +import java.util.Base64 + +/** + * Client-side payment-channels primitives: PDA/ATA derivation, the 48-byte + * voucher preimage, and the `open` instruction + payer-signed (operator-fee- + * payer-unsigned) open transaction the session client broadcasts via the + * operator. + * + * Mirrors the client-facing subset of `solana_pay_core::payment_channels` + * (`rust/crates/core/src/payment_channels.rs`). The server-only primitives + * (ed25519 verify precompile, settle/finalize/distribute, the BLAKE3 + * distribution hash) are intentionally omitted: this SDK is client-only and the + * channel `open` passes its recipients inline rather than hashed. + */ +object PaymentChannels { + /** Canonical payment-channels program ID deployed to Surfnet. */ + const val PROGRAM_ID = "GuoKrzaBiZnW5DvJ3yZVE7xHqbcBvaX9SH6P6Cn9gNvc" + + /** Rent sysvar account. */ + const val RENT_SYSVAR_ID = "SysvarRent111111111111111111111111111111111" + + /** Default payment-channel close grace period, in seconds. */ + const val DEFAULT_GRACE_PERIOD_SECONDS: UInt = 900u + + private const val OPEN_DISCRIMINATOR: Byte = 1 + private val CHANNEL_SEED = "channel".encodeToByteArray() + private val EVENT_AUTHORITY_SEED = "event_authority".encodeToByteArray() + + /** A recipient split: `bps` basis points of the settled balance. */ + data class Distribution(val recipient: PublicKey, val bps: Int) { + init { + require(bps in 0..0xFFFF) { "bps must fit in u16 (got $bps)" } + } + } + + /** Inputs to the channel `open` instruction. */ + data class OpenChannelParams( + val payer: PublicKey, + val payee: PublicKey, + val mint: PublicKey, + val authorizedSigner: PublicKey, + val salt: ULong, + val deposit: ULong, + val gracePeriod: UInt, + val recipients: List, + val tokenProgram: PublicKey, + val programId: PublicKey, + ) + + /** Derived channel PDA + base64 (payer-signed, fee-payer-unsigned) open tx. */ + data class OpenTransaction(val channelId: PublicKey, val transaction: String) + + // ── Voucher preimage ── + + /** + * The 48-byte Ed25519 voucher preimage: + * `channelId(32) || cumulativeAmount(u64 LE) || expiresAt(i64 LE)`. + */ + fun voucherMessageBytes(channelId: String, cumulative: ULong, expiresAt: Long): ByteArray { + val channel = PublicKey.fromBase58(channelId) + val out = ByteArray(48) + System.arraycopy(channel.bytes, 0, out, 0, 32) + System.arraycopy(u64Le(cumulative), 0, out, 32, 8) + // i64 little-endian shares the two's-complement bit pattern of u64 LE. + System.arraycopy(u64Le(expiresAt.toULong()), 0, out, 40, 8) + return out + } + + // ── PDA derivation ── + + fun findChannelPda( + payer: PublicKey, + payee: PublicKey, + mint: PublicKey, + authorizedSigner: PublicKey, + salt: ULong, + programId: PublicKey, + ): PublicKey { + val seeds = listOf( + CHANNEL_SEED, + payer.bytes, + payee.bytes, + mint.bytes, + authorizedSigner.bytes, + u64Le(salt), + ) + return Pda.findProgramAddress(seeds, programId).first + } + + fun findEventAuthorityPda(programId: PublicKey): PublicKey = + Pda.findProgramAddress(listOf(EVENT_AUTHORITY_SEED), programId).first + + /** Random u64 channel salt so concurrent opens derive distinct channel PDAs. */ + fun uniqueSalt(): ULong { + val bytes = Ed25519.generateSeed() // 32 CSPRNG bytes; take the low 8. + var value = 0uL + for (i in 0..7) value = value or (bytes[i].toULong() and 0xffuL shl (8 * i)) + return value + } + + // ── Open instruction + transaction ── + + fun buildOpenInstruction(params: OpenChannelParams): Instruction { + val channel = findChannelPda( + params.payer, params.payee, params.mint, params.authorizedSigner, params.salt, params.programId + ) + val payerTokenAccount = Pda.associatedTokenAddress(params.payer, params.mint, params.tokenProgram) + val channelTokenAccount = Pda.associatedTokenAddress(channel, params.mint, params.tokenProgram) + val eventAuthority = findEventAuthorityPda(params.programId) + + // Account order matches the codama-generated `Open` builder exactly. + val accounts = listOf( + AccountMeta.writable(params.payer.toBase58(), signer = true), + AccountMeta.readOnly(params.payee.toBase58()), + AccountMeta.readOnly(params.mint.toBase58()), + AccountMeta.readOnly(params.authorizedSigner.toBase58()), + AccountMeta.writable(channel.toBase58()), + AccountMeta.writable(payerTokenAccount.toBase58()), + AccountMeta.writable(channelTokenAccount.toBase58()), + AccountMeta.readOnly(params.tokenProgram.toBase58()), + AccountMeta.readOnly(Programs.SYSTEM_PROGRAM), + AccountMeta.readOnly(RENT_SYSVAR_ID), + AccountMeta.readOnly(Programs.ASSOCIATED_TOKEN_PROGRAM), + AccountMeta.readOnly(eventAuthority.toBase58()), + AccountMeta.readOnly(params.programId.toBase58()), + ) + + // data = discriminator(1) || borsh(OpenArgs { salt, deposit, gracePeriod, recipients }). + val data = ByteArrayOutputStream() + data.write(byteArrayOf(OPEN_DISCRIMINATOR)) + data.write(u64Le(params.salt)) + data.write(u64Le(params.deposit)) + data.write(u32Le(params.gracePeriod)) + data.write(u32Le(params.recipients.size.toUInt())) + for (entry in params.recipients) { + data.write(entry.recipient.bytes) + data.write(u16Le(entry.bps)) + } + + return Instruction(programId = params.programId.toBase58(), accounts = accounts, data = data.toByteArray()) + } + + /** + * Build a payer-signed (fee-payer-unsigned) channel `open` transaction. The + * `payer` signs to authorize the deposit; the `feePayer` (operator) slot is + * left empty for the server to co-sign before broadcast. + */ + fun buildOpenTransaction( + payer: SolanaSigner, + payee: PublicKey, + mint: PublicKey, + authorizedSigner: PublicKey, + salt: ULong, + deposit: ULong, + gracePeriod: UInt, + recipients: List, + tokenProgram: PublicKey, + programId: PublicKey, + feePayer: PublicKey, + recentBlockhash: ByteArray, + ): OpenTransaction { + val payerPubkey = PublicKey(payer.publicKeyBytes) + val params = OpenChannelParams( + payer = payerPubkey, payee = payee, mint = mint, authorizedSigner = authorizedSigner, + salt = salt, deposit = deposit, gracePeriod = gracePeriod, recipients = recipients, + tokenProgram = tokenProgram, programId = programId, + ) + val channelId = findChannelPda(payerPubkey, payee, mint, authorizedSigner, salt, programId) + val instruction = buildOpenInstruction(params) + val message = Transaction.buildLegacyMessage(feePayer, recentBlockhash, listOf(instruction)) + val signature = payer.sign(message.serialize()) + require(signature.size == 64) { "open signature must be 64 bytes (got ${signature.size})" } + val signerIndex = message.accountKeys.indexOfFirst { it.bytes.contentEquals(payerPubkey.bytes) } + if (signerIndex < 0) { + throw MppException.InvalidTransaction("payer is not in the open transaction account list") + } + val signatures = MutableList(message.header.numRequiredSignatures) { null } + // The payer must land in the signer prefix of the account list; guard the + // index so a non-signer slot throws instead of going out of bounds. + if (signerIndex >= signatures.size) { + throw MppException.InvalidTransaction("payer signer index $signerIndex is outside the required-signer range") + } + signatures[signerIndex] = signature + val txBytes = Transaction.serializeLegacyTransaction(message, signatures) + return OpenTransaction(channelId = channelId, transaction = Base64.getEncoder().encodeToString(txBytes)) + } + + // ── Little-endian helpers ── + + private fun u64Le(value: ULong): ByteArray { + val out = ByteArray(8) + var shift = 0 + for (i in 0..7) { + out[i] = ((value shr shift) and 0xffuL).toByte() + shift += 8 + } + return out + } + + private fun u32Le(value: UInt): ByteArray { + val out = ByteArray(4) + out[0] = (value and 0xffu).toByte() + out[1] = ((value shr 8) and 0xffu).toByte() + out[2] = ((value shr 16) and 0xffu).toByte() + out[3] = ((value shr 24) and 0xffu).toByte() + return out + } + + private fun u16Le(value: Int): ByteArray { + val v = value.toUInt() + return byteArrayOf((v and 0xffu).toByte(), ((v shr 8) and 0xffu).toByte()) + } +} diff --git a/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionClient.kt b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionClient.kt new file mode 100644 index 000000000..3011ba09e --- /dev/null +++ b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionClient.kt @@ -0,0 +1,370 @@ +package com.solana.paykit.protocols.mpp.client + +import com.solana.paykit.paycore.Base58 +import com.solana.paykit.paycore.Base64Url +import com.solana.paykit.paycore.MppException +import com.solana.paykit.paycore.PaymentChannels +import com.solana.paykit.paycore.PublicKey +import com.solana.paykit.paycore.SolanaSigner +import com.solana.paykit.paycore.defaultTokenProgramForCurrency +import com.solana.paykit.paycore.resolveStablecoinMint +import com.solana.paykit.protocols.mpp.core.CanonicalJson +import com.solana.paykit.protocols.mpp.core.ChallengeEcho +import com.solana.paykit.protocols.mpp.core.ClosePayload +import com.solana.paykit.protocols.mpp.core.DEFAULT_SESSION_EXPIRES_AT +import com.solana.paykit.protocols.mpp.core.MppHeaders +import com.solana.paykit.protocols.mpp.core.OpenPayload +import com.solana.paykit.protocols.mpp.core.PaymentChallenge +import com.solana.paykit.protocols.mpp.core.SessionAction +import com.solana.paykit.protocols.mpp.core.SessionActionCodec +import com.solana.paykit.protocols.mpp.core.SessionMode +import com.solana.paykit.protocols.mpp.core.SessionPullVoucherStrategy +import com.solana.paykit.protocols.mpp.core.SessionRequest +import com.solana.paykit.protocols.mpp.core.SignedVoucher +import com.solana.paykit.protocols.mpp.core.TopUpPayload +import com.solana.paykit.protocols.mpp.core.VoucherData +import com.solana.paykit.protocols.mpp.core.VoucherPayload +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.encodeToJsonElement + +/** + * A live metered session bound to one payment channel. + * + * Holds the cumulative watermark, request nonce, and voucher expiry, and signs + * monotonically-increasing vouchers with the session signer. Mirrors the Go + * reference `ActiveSession` including the `ReconcileSettled` lost-response + * clamp. Sessions are single-threaded (not thread-safe), matching Rust `&mut`. + */ +class ActiveSession( + val channelId: String, + private val signer: SolanaSigner, + cumulative: ULong = 0uL, + expiresAt: Long = DEFAULT_SESSION_EXPIRES_AT, +) { + var cumulative: ULong = cumulative + private set + var nonce: ULong = 0uL + private set + var expiresAt: Long = expiresAt + private set + + fun setExpiresAt(value: Long) { + expiresAt = value + } + + /** base58 of the session signer's public key (the on-chain authorized signer). */ + fun authorizedSigner(): String = signer.address + + fun channelIdString(): String = channelId + + // ── Voucher signing ── + + /** Sign a voucher at an absolute cumulative without advancing the watermark. */ + fun prepareVoucher(cumulative: ULong): SignedVoucher { + if (cumulative <= this.cumulative) { + throw MppException.InvalidTransaction( + "voucher cumulative $cumulative must exceed current watermark ${this.cumulative}" + ) + } + val data = VoucherData( + channelId = channelId, + cumulative = cumulative.toString(), + expiresAt = expiresAt, + nonce = (nonce + 1uL).toLong(), + ) + val signature = signer.sign(data.messageBytes()) + return SignedVoucher(data, Base58.encode(signature)) + } + + fun prepareIncrement(amount: ULong): SignedVoucher = prepareVoucher(addToWatermark(amount)) + + /** + * Advance the watermark to a recorded voucher: rejects a voucher bound to a + * different channel, a non-increasing cumulative, or an unparseable + * cumulative; advances the nonce to at least `nonce + 1` (or the voucher's + * nonce when higher). Mirrors Go `RecordVoucher`. + */ + fun recordVoucher(voucher: SignedVoucher) { + if (voucher.data.channelId != channelIdString()) { + throw MppException.InvalidTransaction( + "voucher channel ${voucher.data.channelId} does not match active session ${channelIdString()}" + ) + } + val cumulative = voucher.data.cumulative.toULongOrNull() + ?: throw MppException.InvalidTransaction("invalid voucher cumulative") + if (cumulative <= this.cumulative) { + throw MppException.InvalidTransaction( + "voucher cumulative $cumulative must exceed current watermark ${this.cumulative}" + ) + } + this.cumulative = cumulative + var candidate = this.nonce + 1uL + val voucherNonce = voucher.data.nonce?.toULong() + if (voucherNonce != null && voucherNonce > candidate) candidate = voucherNonce + this.nonce = candidate + } + + /** + * Reconcile the watermark to a server-settled cumulative (e.g. a replayed + * commit receipt): advance only when ahead, never regress, bump the nonce on + * advance. Mirrors Go `ReconcileSettled` (the #162 lost-response fix). + */ + fun reconcileSettled(settled: ULong) { + if (settled > cumulative) { + cumulative = settled + nonce += 1uL + } + } + + fun signVoucher(cumulative: ULong): SignedVoucher { + val voucher = prepareVoucher(cumulative) + recordVoucher(voucher) + return voucher + } + + fun signIncrement(amount: ULong): SignedVoucher = signVoucher(addToWatermark(amount)) + + // ── Action builders ── + + fun voucherAction(amount: ULong): SessionAction = SessionAction.Voucher(VoucherPayload(signIncrement(amount))) + + /** Cooperative close; a `finalIncrement` > 0 signs one last voucher first. */ + fun closeAction(finalIncrement: ULong?): SessionAction { + val voucher = if (finalIncrement != null && finalIncrement > 0uL) signIncrement(finalIncrement) else null + return SessionAction.Close(ClosePayload(channelId, voucher)) + } + + fun openAction(deposit: ULong, openTxSignature: String): SessionAction = + SessionAction.Open(OpenPayload.push(channelId, deposit.toString(), authorizedSigner(), openTxSignature)) + + fun openPaymentChannelAction( + mode: SessionMode = SessionMode.PUSH, + deposit: ULong, + payer: String, + payee: String, + mint: String, + salt: ULong, + gracePeriod: UInt, + signature: String, + ): SessionAction = SessionAction.Open( + OpenPayload.paymentChannel( + mode, channelId, deposit.toString(), payer, payee, mint, salt, gracePeriod, authorizedSigner(), signature + ) + ) + + /** + * Build a pull-mode (SPL delegation) open action. The channel ID is used as + * the token account, so callers should construct the [ActiveSession] with + * the delegated token account pubkey as the channel ID. Mirrors Go + * `OpenPullAction` and Rust `open_pull_action`. + */ + fun openPullAction(approvedAmount: ULong, owner: String, approveTxSignature: String): SessionAction = + SessionAction.Open(OpenPayload.pull(channelId, approvedAmount.toString(), owner, authorizedSigner(), approveTxSignature)) + + fun topupAction(newDeposit: ULong, topupTxSignature: String): SessionAction = + SessionAction.TopUp(TopUpPayload(channelId, newDeposit.toString(), topupTxSignature)) + + private fun addToWatermark(amount: ULong): ULong { + val sum = cumulative + amount + if (sum < cumulative) { + throw MppException.InvalidTransaction("voucher cumulative overflow adding $amount to $cumulative") + } + return sum + } +} + +// ── Payment-channel session opener ── + +/** Placeholder operator signature; the server fills its fee-payer slot before broadcast. */ +const val PENDING_SERVER_SIGNATURE: String = + "1111111111111111111111111111111111111111111111111111111111111111" + +/** Derived channel parameters for an open. */ +data class PaymentChannelOpen( + val channelId: PublicKey, + val payer: PublicKey, + val payee: PublicKey, + val mint: PublicKey, + val authorizedSigner: PublicKey, + val salt: ULong, + val deposit: ULong, + val gracePeriod: UInt, + val recipients: List, + val tokenProgram: PublicKey, + val programId: PublicKey, +) { + fun openPayload(mode: SessionMode, signature: String): OpenPayload = + OpenPayload.paymentChannel( + mode = mode, + channelId = channelId.toBase58(), + deposit = deposit.toString(), + payer = payer.toBase58(), + payee = payee.toBase58(), + mint = mint.toBase58(), + salt = salt, + gracePeriod = gracePeriod, + authorizedSigner = authorizedSigner.toBase58(), + signature = signature, + ) +} + +/** Per-channel open overrides; unset fields fall back to challenge-derived defaults. */ +data class PaymentChannelOpenOptions( + val deposit: ULong? = null, + val gracePeriod: UInt? = null, + val programId: PublicKey? = null, + val recipients: List? = null, + val salt: ULong? = null, + val tokenProgram: PublicKey? = null, +) + +data class PaymentChannelSessionOpenOptions( + val open: PaymentChannelOpenOptions = PaymentChannelOpenOptions(), + val signature: String? = null, + val cumulative: ULong? = null, + val expiresAt: Long? = null, +) + +/** Result of opening a payment-channel session client-side. */ +data class PaymentChannelSessionOpen( + val open: PaymentChannelOpen, + val session: ActiveSession, + val action: SessionAction, +) + +object PaymentChannelSession { + private val json = Json { + encodeDefaults = false + explicitNulls = false + ignoreUnknownKeys = true + } + + /** + * Build a pull + clientVoucher payment-channel session open. The payer + * partial-signs the open transaction; the operator (fee payer) co-signs and + * broadcasts. `recentBlockhash` is base58. Mirrors + * `create_payment_channel_session_opener`. + */ + fun open( + request: SessionRequest, + payerSigner: SolanaSigner, + sessionSigner: SolanaSigner, + recentBlockhash: String, + options: PaymentChannelSessionOpenOptions = PaymentChannelSessionOpenOptions(), + ): PaymentChannelSessionOpen { + ensureClientVoucherPull(request) + val authorizedSigner = PublicKey(sessionSigner.publicKeyBytes) + val feePayer = PublicKey.fromBase58(request.operator) + val payer = PublicKey(payerSigner.publicKeyBytes) + val open = deriveOpen(request, payer, authorizedSigner, options.open) + + val blockhash = Base58.decode(recentBlockhash) + if (blockhash.size != 32) { + throw MppException.InvalidTransaction("recentBlockhash must decode to 32 bytes") + } + val tx = PaymentChannels.buildOpenTransaction( + payer = payerSigner, + payee = open.payee, + mint = open.mint, + authorizedSigner = open.authorizedSigner, + salt = open.salt, + deposit = open.deposit, + gracePeriod = open.gracePeriod, + recipients = open.recipients, + tokenProgram = open.tokenProgram, + programId = open.programId, + feePayer = feePayer, + recentBlockhash = blockhash, + ) + + val session = ActiveSession( + channelId = open.channelId.toBase58(), + signer = sessionSigner, + cumulative = options.cumulative ?: 0uL, + expiresAt = options.expiresAt ?: DEFAULT_SESSION_EXPIRES_AT, + ) + val signature = options.signature ?: PENDING_SERVER_SIGNATURE + val action = SessionAction.Open(open.openPayload(SessionMode.PULL, signature).withTransaction(tx.transaction)) + return PaymentChannelSessionOpen(open, session, action) + } + + private fun ensureClientVoucherPull(request: SessionRequest) { + if (!request.modes.contains(SessionMode.PULL)) { + throw MppException.InvalidTransaction("session challenge does not advertise pull mode") + } + if (request.pullVoucherStrategy != SessionPullVoucherStrategy.CLIENT_VOUCHER) { + throw MppException.InvalidTransaction("session challenge does not advertise pull + clientVoucher") + } + } + + private fun deriveOpen( + request: SessionRequest, + payer: PublicKey, + authorizedSigner: PublicKey, + options: PaymentChannelOpenOptions, + ): PaymentChannelOpen { + val mintString = resolveStablecoinMint(request.currency, request.network) + ?: throw MppException.InvalidTransaction("session payment channels require an SPL token") + val mint = PublicKey.fromBase58(mintString) + val payee = PublicKey.fromBase58(request.recipient) + val deposit = options.deposit + ?: request.cap.toULongOrNull() + ?: throw MppException.InvalidTransaction("invalid session cap: ${request.cap}") + val gracePeriod = options.gracePeriod ?: PaymentChannels.DEFAULT_GRACE_PERIOD_SECONDS + val programId = options.programId + ?: request.programId?.let { PublicKey.fromBase58(it) } + ?: PublicKey.fromBase58(PaymentChannels.PROGRAM_ID) + val tokenProgram = options.tokenProgram + ?: PublicKey.fromBase58(defaultTokenProgramForCurrency(request.currency, request.network)) + val recipients = options.recipients + ?: request.splits.map { + try { + PaymentChannels.Distribution(PublicKey.fromBase58(it.recipient), it.bps) + } catch (error: IllegalArgumentException) { + throw MppException.InvalidTransaction("invalid session split: ${error.message}") + } + } + val salt = options.salt ?: PaymentChannels.uniqueSalt() + val channelId = PaymentChannels.findChannelPda(payer, payee, mint, authorizedSigner, salt, programId) + return PaymentChannelOpen( + channelId = channelId, payer = payer, payee = payee, mint = mint, authorizedSigner = authorizedSigner, + salt = salt, deposit = deposit, gracePeriod = gracePeriod, recipients = recipients, + tokenProgram = tokenProgram, programId = programId, + ) + } + + /** + * Build an `Authorization: Payment ` value for a + * session action, echoing the challenge. Mirrors Go `SerializeSessionCredential`. + */ + fun serializeSessionCredential(challenge: ChallengeEcho, action: SessionAction): String { + val tree = buildJsonObject { + put("challenge", json.encodeToJsonElement(ChallengeEcho.serializer(), challenge)) + put("payload", SessionActionCodec.toJsonObject(action)) + } + val canonical = CanonicalJson.encode(tree) + return "${MppHeaders.PAYMENT_SCHEME} ${Base64Url.encode(canonical.encodeToByteArray())}" + } + + /** Decode the base64url-encoded session request carried by a challenge. */ + fun sessionRequest(challenge: PaymentChallenge): SessionRequest { + if (challenge.request.length > MppHeaders.MAX_TOKEN_LEN) { + throw MppException.InvalidHeader + } + return try { + json.decodeFromString(SessionRequest.serializer(), Base64Url.decode(challenge.request).decodeToString()) + } catch (error: IllegalArgumentException) { + throw MppException.InvalidJson(error) + } catch (error: kotlinx.serialization.SerializationException) { + throw MppException.InvalidJson(error) + } + } + + /** Require a `solana`/`session` challenge before opening a session. */ + fun requireSolanaSession(challenge: PaymentChallenge) { + if (challenge.method != "solana" || challenge.intent != "session") { + throw MppException.UnsupportedChallenge(challenge.method, challenge.intent) + } + } +} diff --git a/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumer.kt b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumer.kt new file mode 100644 index 000000000..aa654e57c --- /dev/null +++ b/kotlin/src/main/kotlin/com/solana/paykit/protocols/mpp/client/SessionConsumer.kt @@ -0,0 +1,83 @@ +package com.solana.paykit.protocols.mpp.client + +import com.solana.paykit.paycore.MppException +import com.solana.paykit.protocols.mpp.core.CommitPayload +import com.solana.paykit.protocols.mpp.core.CommitReceipt +import com.solana.paykit.protocols.mpp.core.CommitStatus +import com.solana.paykit.protocols.mpp.core.MeteredEnvelope +import com.solana.paykit.protocols.mpp.core.MeteringDirective + +/** Transport that commits a signed voucher to the session server and returns a receipt. */ +fun interface CommitTransport { + fun commit(directive: MeteringDirective, payload: CommitPayload): CommitReceipt +} + +/** + * Client side of metered delivery: signs a voucher per directive, commits it + * through the transport, and advances the local watermark only on success. + * Mirrors Go `SessionConsumer`. + */ +class SessionConsumer(val session: ActiveSession, val transport: CommitTransport) { + /** Validate the directive against the active session and wrap it for ack. */ + fun